Cómo configurar un script para que se ejecute cuando un puerto recibe un mensaje

12

Me pregunto cómo hacer que un script de shell escuche en un determinado puerto (¿tal vez usando netcat?). Con suerte, para que cuando se envíe un mensaje a ese puerto, el script grabe el mensaje y luego ejecute una función.

Ejemplo:

  1. La computadora 1 tiene el script ejecutándose en segundo plano, el script abrió el puerto 1234 al tráfico entrante

  2. La computadora 2 envía el mensaje "hola mundo" al puerto 1234 de la computadora 1

  3. El script en la computadora 1 registra el mensaje "hello world" en una variable $ MESSAGE

  4. El script ejecuta la función ahora que se ha configurado la variable $ MESSAGE

¿Cómo hago para poner esto?

Daniel
fuente

Respuestas:

12

Debería ser posible con socat.

Escriba dicho script "getmsg.sh" para recibir un mensaje a través de stdin:

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

Luego ejecute este socatcomando para invocar nuestro script para cada conexión tcp en el puerto 7777:

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

Enviar un mensaje de prueba desde otro shell:

echo "message 1" | netcat localhost 7777
rudimeier
fuente
¿Lo has probado?
Reescrito y probado ahora;)
rudimeier
1
Su solución me inspiró y encontré una forma que funciona con netcat: nc -l 7777 | ./getmsg.sh
Daniel
Me alegra escuchar eso. Pero netcatexiste después de una conexión. socatharía lo mismo si elimina ", fork" de mi línea de comando.
rudimeier
7

La forma UCSPI-TCP

Hay conjuntos de herramientas distintos de netcat. Aquí le mostramos cómo usar algunos de ellos. Todos suponen la existencia de un servicescript que ejecuta su func, sea lo que sea:

#! / bin / sh
mientras lee -r MENSAJE
hacer
    echo 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
hecho

Las variables de entorno TCPREMOTEIPy TCPREMOTEPORTestán definidas por el protocolo UCSPI-TCP.

La secuencia de comandos se genera como un proceso individual por conexión TCP utilizando los diversos conjuntos de herramientas. En lo que sigue, las herramientas se muestran tal como se usan dentro de un script corto. Tal script, llamado convencionalmente run, es cómo uno los ejecutaría bajo un administrador de servicio familiar daemontools. Por supuesto, pueden invocarse directamente.

Bernstein ucspi-tcp

Con el ucspi-tcp de Daniel J. Bernstein, se tcpservergenera el serviceguión:

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

Hay versiones mejoradas compatibles con IPv6 de Bernstein ucspi-tcp. Con Erwin Hoffman, tcpserverintenta manejar tanto IPv4 como IPv6 en uno (si el sistema operativo lo admite, algunos no lo hacen) y genera el servicescript:

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

Bercot s6-networking, s6 y execline

Con la red s6 de Laurent Bercot, s6-tcpserver4y s6-tcpserver6maneje IPv4 e IPv6 por separado, y genere el servicescript:

#! / command / execlineb
s6-tcpserver4 -v 0.0.0.0 7777 
./Servicio
#! / command / execlineb
s6-tcpserver6 -v :: 0 7777 
./Servicio

Uno puede construir servidores más complejos mediante la interposición de herramientas como s6-tcpserver-accessy s6-applyuidgiden la cadena inmediatamente antes ./service.

herramientas UCSPI nosh

Con el conjunto de herramientas nosh, tcp-socket-listenescucha en el socket TCP, nuevamente manejando IPv4 e IPv6 de manera simultánea si el sistema operativo admite hacerlo, y cadenas a las tcp-socket-acceptque a su vez genera el servicescript:

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

O uno ejecuta dos procesos separados, en sistemas operativos como OpenBSD:

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

Uno puede construir servidores más complejos interponiendo herramientas como ucspi-socket-rules-checky setuidgiden la cadena.

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
usuario sin privilegios setuidgid
tcp-socket-accept --verbose --localname 0
ucspi-socket-rules-check --verbose
./Servicio

Pape ipsvd

Con el ipsvd de Gerrit Pape, tcpsvdgenera el serviceguión:

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

UCSPI-UDP

El servicescript común puede manejar cuando la entrada estándar es un socket de flujo . Pero no especificó TCP explícitamente.

Aunque algunos de los juegos de herramientas mencionados anteriormente se pueden usar para construir servidores UDP de manera similar a cómo uno puede usarlos para construir servidores TCP (cf udp-socket-listenin nosh), es complicado construir el programa de servicio real con script de shell, ya que los componentes integrados de shell no necesariamente se adapta bien cuando la entrada estándar es un socket de datagrama .

Otras lecturas

JdeBP
fuente
0

Esto también se puede hacer con lo udpsvdque está disponible en Ubuntu / Debian ( ver página de manual ), así como integrado en busybox. Ejemplo:

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

Reemplace catcon su script de shell para ejecutar, stdin es el paquete.

Con netcat, puede ejecutar en un bucle para seguir escuchando y pasar cada paquete a myscript:

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

Si desea pasar todos los paquetes recibidos como una secuencia a una sola invocación de su script:

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