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.sh
listener1
listener2
while
Eine 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.sh
Prozess senden, wird dieser kill
sein 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
wait
integrierte Programm auf einen asynchronen Befehl wartet, führt der Empfang eines Signals, für das ein Trap gesetzt wurde, dazu, dass daswait
integrierte Programm sofort mit einem Beendigungsstatus größer als zurückkehrt128
, woraufhin der Trap ausgeführt wird.
Dies bedeutet, dass es aplay
im Hintergrund und wait
dafü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 nc
nicht benachrichtigt wird.
Vielleicht dasgesamteAnsatz kann durch einen einzigen ersetzt werden socat
:
socat TCP-LISTEN:9001,fork EXEC:'aplay -'
Dank ihm fork
können mehrere Clients auf demselben Port bedient werden. Verwenden Sie die -T
Option (siehe man 1 socat
), um veraltete Verbindungen zu beenden. Auch ohne -T
sie solltenZeitüberschreitung irgendwanntrotzdem. Die Lösung ist jedoch anfällig für einen DOS-Angriff.