Comment définir un script à exécuter lorsqu'un port reçoit un message

12

Je me demande comment obtenir un script shell pour écouter sur un certain port (peut-être en utilisant netcat?). Espérons que pour qu'un message soit envoyé à ce port, le script enregistre le message puis exécute une fonction.

Exemple:

  1. L'ordinateur 1 a le script exécuté en arrière-plan, le script a ouvert le port 1234 au trafic entrant

  2. L'ordinateur 2 envoie un message "Bonjour tout le monde" au port 1234 de l'ordinateur 1

  3. Le script sur l'ordinateur 1 enregistre le message "bonjour le monde" dans une variable $ MESSAGE

  4. Le script exécute la fonction maintenant que la variable $ MESSAGE a été définie

Comment dois-je procéder pour faire un don?

Daniel
la source

Réponses:

12

Devrait être possible avec socat.

Écrivez un tel script "getmsg.sh" pour recevoir un message via stdin:

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

Exécutez ensuite cette socatcommande pour appeler notre script pour chaque connexion TCP sur le port 7777:

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

Envoyez un message de test à partir d'un autre shell:

echo "message 1" | netcat localhost 7777
rudimeier
la source
L'avez-vous testé?
Réécrit et testé maintenant;)
rudimeier
1
J'ai été inspiré par votre solution et j'ai trouvé un moyen qui fonctionne avec netcat: nc -l 7777 | ./getmsg.sh
Daniel
Content de l'entendre. Mais netcatexiste après une connexion. socatferait de même si vous supprimez ", fork" de ma ligne de commande.
rudimeier
7

La voie UCSPI-TCP

Il existe des jeux d'outils autres que netcat. Voici comment en utiliser quelques-uns. Ils présument tous l'existence d'un servicescript qui exécute votre func, quel qu'il soit:

#! / bin / sh
en lisant -r MESSAGE
faire
    écho 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
terminé

Les variables d'environnement TCPREMOTEIPet TCPREMOTEPORTsont définies par le protocole UCSPI-TCP.

Le script est généré comme un processus individuel par connexion TCP à l'aide des différents jeux d'outils. Dans ce qui suit, les outils sont présentés comme utilisés dans un court script. Un tel script, conventionnellement nommé run, est de savoir comment les exécuter sous un gestionnaire de services de la famille daemontools. Ils peuvent bien entendu être invoqués directement.

Bernstein ucspi-tcp

Avec ucspi-tcp de Daniel J. Bernstein, donne naissance tcpserverau servicescript:

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

Il existe des versions améliorées compatibles IPv6 de Bernstein ucspi-tcp. Avec Erwin Hoffman, tcpservertente de gérer à la fois IPv4 et IPv6 en un (si le système d'exploitation le prend en charge, quelques-uns ne le font pas) et génère le servicescript:

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

Bercot s6-networking, s6 et execline

Avec s6-réseau de Laurent Bercot, s6-tcpserver4et s6-tcpserver6gérer IPv4 et IPv6 séparément, et reproduire le servicescénario:

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

On peut construire des serveurs plus complexes en interposant des outils tels que s6-tcpserver-accesset s6-applyuidgiddans la chaîne immédiatement avant ./service.

nosh UCSPI tools

Avec le jeu d'outils nosh, tcp-socket-listenécoute sur le socket TCP, gérant à nouveau IPv4 et IPv6 simultanément si le système d'exploitation le prend en charge, et les chaînes tcp-socket-acceptauxquelles à son tour génère le servicescript:

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

Ou on exécute deux processus distincts, sur des systèmes d'exploitation tels que OpenBSD:

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

On peut construire des serveurs plus complexes en interposant des outils tels que ucspi-socket-rules-checket setuidgiddans la chaîne.

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
setuidgid utilisateur non privilégié
tcp-socket-accept --verbose --localname 0
ucspi-socket-rules-check --verbose
./un service

Pape ipsvd

Avec l'ipsvd de Gerrit Pape, lance tcpsvdle servicescript:

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

UCSPI-UDP

Le servicescript commun peut gérer lorsque l'entrée standard est une socket de flux . Mais vous n'avez pas spécifié explicitement TCP.

Bien que certaines des boîtes à outils susmentionnées puissent être utilisées pour construire des serveurs UDP de la même manière que la façon dont on peut les utiliser pour construire des serveurs TCP (cf. udp-socket-listenen nosh), il est difficile de construire le programme de service réel avec un script shell, car les buildins du shell ne le font pas nécessairement faire face lorsque l'entrée standard est une prise de datagramme .

Lectures complémentaires

JdeBP
la source
0

Cela peut également être fait avec udpsvdqui est disponible sur Ubuntu / Debian ( voir la page de manuel ) ainsi que intégré à busybox. Exemple:

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

Remplacez catpar votre script shell pour exécuter, stdin est le paquet.

Avec netcat, vous pouvez exécuter en boucle pour continuer à écouter et passer chaque paquet à myscript:

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

Si vous souhaitez transmettre tous les paquets reçus sous forme de flux à une seule invocation de votre script:

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