13

BASH スクリプト内では、ファイルシステムに登録された名前付きパイプ (FIFO) を使用して相互通信する複数のプロセスをバックグラウンドで実行できます。これの例は次のとおりです。

#!/bin/bash
mkfifo FIFO

# BG process 1
while :; do echo x; done & >FIFO

# BG process 2
while :; do read; done & <FIFO

exit

おそらく何らかのファイル記述子リダイレクトを使用して、ファイルシステムで FIFO を使用せずに、スクリプトのバックグラウンド プロセス間で同じ相互通信を行うことが可能かどうか疑問に思います。

4

5 に答える 5

5

Bash 4 にはcoprocessesがあります。

匿名の名前付きパイプ ( Bash 2、3、または 4 のプロセス置換とも呼ばれる) を使用することもできます。

于 2012-06-02T14:33:45.260 に答える
3

スクリプトの標準ストリームをネットワークソケットに接続できるようにする (aka ) を使用できますncnetcatもちろんlocalhostでも動作するので、スクリプト間のIPCにも使えます。おまけに、別のホストでスクリプトを実行できる可能性があります。これは、FIFO では不可能です (NFS では可能かもしれませんが、NFS が既に整っていない限り、セットアップはかなり面倒です)。

于 2012-06-04T13:21:17.170 に答える
0

信号の使用を検討しましたか? (引数を渡さずに) イベントをトリガーすることだけが必要な場合は、 kill と trap を使用すると完全に機能します (ただし、セマンティクスには注意してください。たとえば、SIGUSR1 を使用してください)。

ただし、次の例のように、ロジックを作り直す必要がある場合があります。

subprocess_finished()
{
    np=$( jobs -p | wc -l )
}

start_processing()
{
    myfile="$1"
    # DO SOMETHING HERE!!
    kill -SIGUSR1 $2
}

CPUS=$( lscpu | grep "^CPU(s):" | rev | cut -f 1 -d ' ' | rev )
POLLPERIOD=5  # 5s between each poll
np=0
trap subprocess_finished SIGUSR1

for myfile in *
do 
        start_processing "$myfile" $$ &
        np=$( jobs -p | wc -l )
        echo "$( date +'%Y-%m-%d %H:%M:%S' ) [$!] Starting #$np on $CPUS: $myfile"

        if [ $np -eq $CPUS ] 
        then
            # Wait for one CPU to be free
            trap subprocess_finished SIGUSR1
            while [ $np -eq $CPUS ]
            do
                sleep $POLLPERIOD
            done
        fi
    done
done

# wait for the last subprocesses
while [ ! -z "$( jobs -rp )" ]
do
    sleep $POLLPERIOD
done
于 2014-03-10T11:16:59.320 に答える