PID des Prozesses in einer durch ein Skript gestarteten Schleife

PID des Prozesses in einer durch ein Skript gestarteten Schleife

Ich habe eine Reihe von Prozessen über ein Bash-Skript gestartet, die über Netcat auf Audio-Streams warten und diese wiedergeben, die an verschiedenen Ports ankommen:

#!/bin/bash
# listener.sh

while :
do
    nc -l 900$1 | aplay - 
    sleep 1
done

exit 0

Dieses Skript wird in einem anderen Skript mit Argumenten zum Definieren eindeutiger Ports gestartet. zB.

    #!/bin/bash
    # startlisterners.sh

    if [ ! -f /tmp/listener1.pid ]; then
         nohup  listener.sh 1 &
        echo $! > /tmp/listener1.pid
    fi
    if [ ! -f /tmp/listener2.pid ]; then
         nohup  listener.sh 2 &
         echo $! > /tmp/listener2.pid
    fi

    ..... etc.

    exit 0

Ich muss in der Lage sein, in regelmäßigen Abständen selektiv Instanzen von „aplay“ in den Indizes zu beenden, während die Indizes selbst weiter ausgeführt werden.

Wie kann ich auf die einzelnen PIDs jedes Aplay-Prozesses zugreifen?

Antwort1

Anstatt

nc -l 900$1 | aplay - 
sleep 1

laufen

nc -l "900$1" | aplay - &
   # here you can use $!
wait
sleep 1

Jetzt können Sie beispielsweise in eine vordefinierte Datei # here you can use $!schreiben, wenn es liest . Dieser Ansatz erfordert möglicherweise die Kenntnis der Dateinummer ( usw. ), damit eine Datei mit der richtigen Nummer verwendet werden kann.$!listener.shlistener1listener2


whileEine andere Möglichkeit besteht darin, vor in eine Falle zu definieren listener.sh:

trap 'kill "$!"' SIGUSR2

Wenn dies implementiert ist und Sie SIGUSR2( kill -s SIGUSR2 …) an einen listener.shProzess senden, wird dieser killsein eigenes ausführen aplay. Dank der Dateien kennen Sie die PIDs Ihrer Listener bereits /tmp/listener*.pid.

Denken Sie daran, wasdas Handbuchsagt:

Wenn Bash auf die Ausführung eines Befehls wartet und ein Signal empfängt, für das ein Trap gesetzt wurde, wird der Trap erst ausgeführt, wenn der Befehl abgeschlossen ist. Wenn Bash über das waitintegrierte Programm auf einen asynchronen Befehl wartet, führt der Empfang eines Signals, für das ein Trap gesetzt wurde, dazu, dass das waitintegrierte Programm sofort mit einem Beendigungsstatus größer als zurückkehrt 128, woraufhin der Trap ausgeführt wird.

Dies bedeutet, dass es aplayim Hintergrund und waitdafür ausgeführt werden sollte (wie oben).


Ich kann nur vermuten, dass Sie mehrere Listener ausführen, um mehrere Clients bedienen zu können (immer noch höchstens ein Client pro Port zu einem bestimmten Zeitpunkt). Dann müssen Sie gelegentlich kill ausführen aplay, z. B. wenn ein Client stillschweigend verschwindet und ncnicht benachrichtigt wird.

Vielleicht dasgesamteAnsatz kann durch einen einzigen ersetzt werden socat:

socat TCP-LISTEN:9001,fork EXEC:'aplay -'

Dank ihm forkkönnen mehrere Clients auf demselben Port bedient werden. Verwenden Sie die -TOption (siehe man 1 socat), um veraltete Verbindungen zu beenden. Auch ohne -Tsie solltenZeitüberschreitung irgendwanntrotzdem. Die Lösung ist jedoch anfällig für einen DOS-Angriff.

verwandte Informationen