Como definir um script para executar quando uma porta recebe uma mensagem

12

Eu estou querendo saber como obter um script de shell para ouvir em uma determinada porta (talvez usando o netcat?). Esperamos que, quando uma mensagem for enviada para essa porta, o script registre a mensagem e execute uma função.

Exemplo:

  1. O computador 1 tem o script em execução em segundo plano, o script abriu a porta 1234 para o tráfego de entrada

  2. O computador 2 envia a mensagem "olá mundo" para a porta 1234 do computador 1

  3. O script no Computador 1 registra a mensagem "olá mundo" em uma variável $ MESSAGE

  4. O script executa a função agora que a variável $ MESSAGE foi definida

Como faço para doar isso?

Daniel
fonte

Respostas:

12

Deve ser possível com socat.

Escreva um script "getmsg.sh" para receber uma mensagem via stdin:

#!/bin/bash
read MESSAGE
echo "PID: $$"
echo "$MESSAGE"

Em seguida, execute este socatcomando para chamar nosso script para cada conexão tcp na porta 7777:

socat -u tcp-l:7777,fork system:./getmsg.sh

Envie uma mensagem de teste de outro shell:

echo "message 1" | netcat localhost 7777
rudimeier
fonte
Você já testou?
Reescrito e testado agora;)
rudimeier 5/10
1
Fui inspirado pela sua solução e encontrei uma maneira que funciona com o netcat: nc -l 7777 | ./getmsg.sh
Daniel
Fico feliz em ouvir isso. Mas netcatexiste após uma conexão. socatfaria o mesmo se você remover ", fork" da minha linha de comando.
Rudimeier 05/10
7

A maneira UCSPI-TCP

Existem outros conjuntos de ferramentas além do netcat. Aqui está como usar alguns deles. Todos eles presumem a existência de um servicescript que executa o seu func, seja ele qual for:

#! / bin / sh
enquanto lê -r MESSAGE
Faz
    eco 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
feito

As variáveis ​​de ambiente TCPREMOTEIPe TCPREMOTEPORTsão definidas pelo protocolo UCSPI-TCP.

O script é gerado como um processo individual por conexão TCP usando os vários conjuntos de ferramentas. A seguir, as ferramentas são mostradas como usadas em um script curto. Esse script, de nome convencional run, é como alguém os executaria sob um gerente de serviços da família daemontools. É claro que eles podem ser invocados diretamente.

Bernstein ucspi-tcp

Com o ucspi-tcp de Daniel J. Bernstein, tcpservergera o servicescript:

#! / bin / sh -e
exec tcpserver -v -P -R -H -l 0 0.0.0.0 7777 ./service

Existem versões aprimoradas para IPv6 do Bernstein ucspi-tcp. Com Erwin Hoffman, as tcpservertentativas de lidar com IPv4 e IPv6 em um (se o sistema operacional suportar isso, alguns não) e geram o servicescript:

#! / bin / sh -e
exec tcpserver -v -P -R -H -l 0 :: 0 7777 ./service

Bercot s6-networking, s6 e execline

Com S6-redes de Laurent Bercot, s6-tcpserver4e s6-tcpserver6lidar com IPv4 e IPv6 separadamente, e gerar o servicescript:

#! / command / execlineb
s6-tcpserver4 -v 0.0.0.0 7777 
./serviço
#! / command / execlineb
s6-tcpserver6 -v :: 0 7777 
./serviço

Pode-se construir servidores mais complexos interpondo ferramentas como s6-tcpserver-accesse s6-applyuidgidna cadeia imediatamente antes ./service.

ferramentas UCSPI nosh

Com o conjunto de ferramentas nosh, tcp-socket-listenescuta no soquete TCP, manipulando novamente IPv4 e IPv6 de forma simultânea se o sistema operacional suportar isso e as cadeias às tcp-socket-acceptquais, por sua vez, gera o servicescript:

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
tcp-socket-accept --verbose --localname 0
./serviço

Ou então, são executados dois processos separados, em sistemas operacionais como o OpenBSD:

#! / bin / nosh
tcp-socket-listen 0.0.0.0 7777
tcp-socket-accept --verbose --localname 0
./serviço
#! / bin / nosh
tcp-socket-listen :: 7777
tcp-socket-accept --verbose --localname ::
./serviço

Pode-se construir servidores mais complexos interpondo ferramentas como ucspi-socket-rules-checke setuidgidna cadeia.

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
usuário não privilegiado setuidgid
tcp-socket-accept --verbose --localname 0
ucspi-socket-rules-check --verbose
./serviço

Pape ipsvd

Com o ipsvd de Gerrit Pape, tcpsvdgera o servicescript:

#! / bin / sh -e
exec tcpsvd -v 0.0.0.0 7777 ./service

UCSPI-UDP

O servicescript comum pode manipular quando a entrada padrão é um soquete de fluxo . Mas você não especificou o TCP explicitamente.

Embora alguns dos kits de ferramentas mencionados acima possam ser usados ​​para criar servidores UDP de maneira semelhante a como se pode usá-los para criar servidores TCP (cf udp-socket-listenem nosh), é complicado criar o programa de serviço real com o shell script, pois os componentes internos do shell não necessariamente lidar bem quando a entrada padrão é um soquete de datagrama .

Leitura adicional

JdeBP
fonte
0

Isso também pode ser feito com o udpsvdque está disponível no Ubuntu / Debian ( consulte a página de manual ), bem como embutido no busybox. Exemplo:

# simple UDP "echo" on port 9998
udpsvd 0.0.0.0 9998 cat

Substitua catpelo seu shell script para executar, stdin é o pacote.

Com netcat, você pode executar um loop para continuar ouvindo e passar cada pacote para myscript:

 while true; do nc -ul 9998 | myscript.sh; done

Se você deseja passar todos os pacotes recebidos como um fluxo para uma única invocação do seu script:

# this will keep listening instead of terminating the process:
nc -kul 9998 |myscript.sh
thom_nic
fonte