スクリプトによって開始されたループ内のプロセスのPID

スクリプトによって開始されたループ内のプロセスのPID

netcatを介して別のポートに到着するオーディオストリームを聞いて再生するために、bashスクリプトを介していくつかのプロセスを開始しました。

#!/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」インスタンスを定期的に選択的に終了する必要があります。

各プレイプロセスの個々の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()をプロセスkill -s SIGUSR2 …に送信すると、独自のものが得られます。ファイルを介してすでにリスナーのPIDを知っています。listener.shkillaplay/tmp/listener*.pid

何を躊躇する手動説明する:

Bashがコマンドが完了するのを待ってトラップが確立されたことを知らせると、コマンドが完了するまでトラップは実行されません。 Bashが組み込み関数を介して非同期コマンドを待機しているときにトラップセットを持つ信号を受信するwaitと、組み込み関数はwaitより大きな終了状態に即座に返され、次に128トラップがすぐに実行されます。

これは、aplayバックグラウンドで実行してwait実行する必要があることを意味します(上記のように)。


複数のクライアントにサービスを提供するために複数のリスナーを実行していると推測できます。その後、aplayクライアントが静かに消えてnc通知を受け取らない場合など、時々killを実行する必要があります。

たぶんこれはみんなメソッドは次のいずれかに置き換えることができますsocat

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

fork同じポートで複数のクライアントにサービスを提供できるためです。古い接続を終了するには、この-Tオプション(参照man 1 socat)を使用してください。彼らなしで-T彼らはしなければなりません最終タイムアウトそれでも。ただし、このソリューションはDOS攻撃に対して脆弱です。

おすすめ記事