私は、bash スクリプトを介して起動された複数のプロセスを持っており、netcat を介して、別々のポートに到着するオーディオ ストリームをリッスンして再生しています。
#!/bin/bash
# listener.sh
while :
do
nc -l 900$1 | aplay -
sleep 1
done
exit 0
このスクリプトは、一意のポートを定義する引数を持つ別のスクリプト内で起動されます。例:
#!/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
定期的に、サブスクリプト自体を実行したまま、サブスクリプト内の「aplay」のインスタンスを選択的に強制終了できるようにする必要があります。
各 aplay プロセスの個別の PID にアクセスするにはどうすればよいでしょうか?
答え1
の代わりに
nc -l 900$1 | aplay -
sleep 1
走る
nc -l "900$1" | aplay - &
# here you can use $!
wait
sleep 1
これで、読み取りを行った場所で、# here you can use $!
たとえば$!
定義済みのファイルに書き込むことができます。この方法では、正しい番号のファイルを使用できるように、その番号 ( など) を知る必要がある場合がありlistener.sh
ます。listener1
listener2
while
別の方法としては、の前にトラップを定義することですlistener.sh
。
trap 'kill "$!"' SIGUSR2
これを実装すると、プロセスにSIGUSR2
( )を送信すると、そのプロセス独自のが送信されます。ファイルのおかげで、リスナーの PID はすでにわかっています。kill -s SIGUSR2 …
listener.sh
kill
aplay
/tmp/listener*.pid
気にするなマニュアル言う:
Bash がコマンドの完了を待機しているときに、トラップが設定されているシグナルを受信した場合、コマンドが完了するまでトラップは実行されません。Bash が組み込みコマンドを介して非同期コマンドを待機している場合
wait
、トラップが設定されているシグナルを受信すると、wait
組み込みコマンドは より大きい終了ステータスで直ちに戻り128
、その直後にトラップが実行されます。
つまり、aplay
バックグラウンドで実行する必要がありますwait
(上記のように)。
複数のクライアントにサービスを提供できるようにするために、複数のリスナーを実行しているとしか思えません (ただし、特定の時点ではポートごとに最大 1 つのクライアントです)。その後、クライアントが静かに消えて通知されないaplay
場合など、時々 kill を実行する必要があります。nc
たぶんこれは全体アプローチは単一の に置き換えることができますsocat
:
socat TCP-LISTEN:9001,fork EXEC:'aplay -'
fork
同じポートで複数のクライアントにサービスを提供できます。古い接続を終了するには、-T
オプション(を参照)を使用します。man 1 socat
-T
最終的にタイムアウトとにかく。ただし、このソリューションは DOS 攻撃に対して脆弱です。