So legen Sie fest, dass ein Skript ausgeführt wird, wenn ein Port eine Nachricht empfängt

12

Ich frage mich, wie ich ein Shell-Skript dazu bringen kann, einen bestimmten Port abzuhören (vielleicht mit Netcat?). Hoffentlich zeichnet das Skript die Nachricht auf, wenn eine Nachricht an diesen Port gesendet wird, und führt dann eine Funktion aus.

Beispiel:

  1. Computer 1 hat das Skript im Hintergrund ausgeführt, das Skript hat Port 1234 für eingehenden Verkehr geöffnet

  2. Computer 2 sendet die Nachricht "Hallo Welt" an Port 1234 von Computer 1

  3. Das Skript auf Computer 1 zeichnet die Nachricht "Hallo Welt" in einer Variablen $ MESSAGE auf

  4. Das Skript wird jetzt ausgeführt, nachdem die Variable $ MESSAGE festgelegt wurde

Wie spende ich das?

Daniel
quelle

Antworten:

12

Sollte mit möglich sein socat.

Schreiben Sie ein solches Skript "getmsg.sh", um eine Nachricht über stdin zu erhalten:

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

Führen Sie dann diesen socatBefehl aus, um unser Skript für jede TCP-Verbindung an Port 7777 aufzurufen:

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

Senden Sie eine Testnachricht von einer anderen Shell:

echo "message 1" | netcat localhost 7777
rudimeier
quelle
Hast du es getestet?
Jetzt umgeschrieben und getestet;)
Rudimeier
1
Ich habe mich von Ihrer Lösung inspirieren lassen und einen Weg gefunden, der mit netcat funktioniert: nc -l 7777 | ./getmsg.sh
Daniel
Freut mich das zu hören. Aber netcatbesteht nach einer Verbindung. socatwürde das gleiche tun, wenn Sie ", fork" von meiner Kommandozeile entfernen.
Rudimeier
7

Der UCSPI-TCP-Weg

Es gibt andere Toolsets als Netcat. Hier erfahren Sie, wie Sie einige davon verwenden. Sie alle setzen die Existenz eines serviceSkripts voraus, das Ihr funcProgramm ausführt , was auch immer das sein mag:

#! / bin / sh
während Sie -r NACHRICHT lesen
tun
    echo 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
erledigt

Die TCPREMOTEIPund TCPREMOTEPORTUmgebungsvariablen werden vom UCSPI-TCP-Protokoll definiert.

Das Skript wird als einzelner Prozess pro TCP-Verbindung unter Verwendung der verschiedenen Toolsets erzeugt. Im Folgenden werden die Werkzeuge so gezeigt, wie sie in einem kurzen Skript verwendet werden. Mit einem solchen Skript, das herkömmlicherweise benannt wird run, wird es unter einem Servicemanager der Daemontools-Familie ausgeführt. Sie können natürlich direkt aufgerufen werden.

Bernstein ucspi-tcp

Mit Daniel J. Bernsteins ucspi-tcp tcpserverentsteht das serviceDrehbuch:

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

Es gibt IPv6-fähige erweiterte Versionen von Bernstein ucspi-tcp. Mit Erwin Hoffman wird tcpserverversucht, sowohl IPv4 als auch IPv6 in einem zu verarbeiten (wenn das Betriebssystem dies unterstützt, einige nicht) und das serviceSkript erzeugt:

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

Bercot S6-Networking, S6 und Execline

Mit Laurent Bercots s6-Netzwerk s6-tcpserver4und s6-tcpserver6IPv4 und IPv6 getrennt behandeln und das serviceSkript erzeugen:

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

Man kann komplexere Server aufbauen, indem man Tools wie s6-tcpserver-accessund s6-applyuidgidin die Kette unmittelbar davor einfügt ./service.

nosh UCSPI-Tools

Hört mit dem Nosh-Toolset tcp-socket-listenden TCP-Socket ab und verarbeitet IPv4 und IPv6 erneut gleichzeitig, wenn das Betriebssystem dies unterstützt, sowie Ketten, an tcp-socket-acceptdie das serviceSkript gesendet wird :

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

Oder man führt zwei separate Prozesse auf Betriebssystemen wie OpenBSD aus:

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

Man kann komplexere Server aufbauen, indem man Tools wie ucspi-socket-rules-checkund setuidgidin die Kette einfügt.

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
setuidgid unprivilegierter Benutzer
tcp-socket-accept --verbose --localname 0
ucspi-socket-rules-check --verbose
./Bedienung

Pape ipsvd

Mit Gerrit Papes ipsvd tcpsvdentsteht das serviceSkript:

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

UCSPI-UDP

Das allgemeine serviceSkript kann verarbeiten, wenn die Standardeingabe ein Stream- Socket ist. Sie haben TCP jedoch nicht explizit angegeben.

Obwohl einige der oben genannten Toolkits verwendet werden können, um UDP-Server auf ähnliche Weise zu erstellen, wie man sie zum Erstellen von TCP-Servern verwenden kann (vgl. udp-socket-listenIn nosh), ist es schwierig, das eigentliche Serviceprogramm mit Shell-Skript zu erstellen, da dies in den Shell-Builds nicht der Fall ist muss gut zurechtkommen, wenn die Standardeingabe ein Datagramm- Socket ist.

Weiterführende Literatur

JdeBP
quelle
0

Dies kann auch mit udpsvdUbuntu / Debian ( siehe Manpage ) sowie in der Busybox integriert erfolgen. Beispiel:

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

Ersetzen Sie es catdurch Ihr Shell-Skript, um es auszuführen. Stdin ist das Paket.

Mit netcatkönnen Sie in einer Schleife laufen, um weiter zuzuhören, und jedes Paket weiterleiten an myscript:

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

Wenn Sie alle empfangenen Pakete als Stream an einen einzelnen Aufruf Ihres Skripts übergeben möchten:

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