私はManager()関数を別々のプロセスとしてx回実行するbashスクリプトを持っています。スクリプト内のすべてのManager()プロセスにメッセージを渡すには?
匿名パイプについて読みましたが、メッセージを共有する方法がわかりません。名前付きパイプを使ってみましたが、プロセスごとに別々の名前付きパイプを作成する必要があると思いますか?
最もエレガントな方法は何ですか?
これは私のコードです。
#!/bin/bash
manager () {
while :
do
echo "read what has been passed to \$line"
done
}
x=1
while [ $x -le 5 ]
do
manager x &
x=$(( $x + 1 ))
done
while :
do
while read line
do
echo "What has been passed through the pipe is ${line}"
# should pass $line to every manager process
done < $1
done
exit 0
ベストアンサー1
あなたが達成したいことを指す用語は次のとおりです。再利用。
これはbashで非常に簡単に行えますが、より高度なbash機能が必要です。
私はあなたが達成したいことを行うと思うスクリプトに基づいてスクリプトを作成しました。以下で説明します。
#!/bin/bash
manager() {
while IFS= read -r line; do
echo "manager[$1:$BASHPID]: $line"
done
}
fds=()
for (( i=0; i<5; i++ )); do
exec {fd}> >(manager $i)
fds+=( $fd )
done
while IFS= read -r line; do
echo "master: $line"
for fd in "${fds[@]}"; do
printf -- '%s\n' "$line" >&$fd
done
done
manager
単にSTDINから読み込み、その識別子と行をSTDOUTに書き込むbash関数です。$BASHPID
代わりにサブシェルを更新しない$$
ので使用します$$
(これはmanager
。
fds
manager
sによって生成されたさまざまなSTDINパイプを指すファイル記述子を保持する配列。
次に、5つの管理者プロセスを繰り返して作成します。私はfor (( ))
あなたが使用する方法の代わりに構文を使用しています。なぜならそれはよりきれいだからです。これはbashに固有のものですが、スクリプトが実行する操作の一部はbashに固有のものであるため、最後まで進むことをお勧めします。
次に私たちは到着しましたexec {fd}> >(manager $i)
。これはより多くのbash関連タスクを実行します。
そのうちの最初のものです{fd}>
。これは、番号が10以上の次の使用可能なファイル記述子を取得し、パイプを開き、パイプの書き込み先を対応するファイル記述子に割り当て、ファイル記述子番号を変数に割り当てます$fd
。
プロセスのSTDINパスを開始し>(manager $i)
、manager $i
デフォルトで交換します。>(manager $i)
したがって、manager
PID 1234から起動すると(オペレーティングシステムに応じて)>(manager $i)
交換できます。/proc/1234/fd/0
したがって、次の使用可能なファイル記述子番号が10で、管理者がPID 1234で始まると仮定すると、コマンドはデフォルトで実行され、exec {fd}> >(manager $i)
bashexec 10>/proc/1234/fd/0
には管理者のSTDINを指すファイル記述子があります。
次に、bashは対応するファイル記述子番号をに入れるので、後で使用できるように$fd
その記述子を配列に追加します。fds
残りはとても簡単です。マスターはSTDINから1行を読み取り、その中のすべてのファイル記述子を介して繰り返し、その行$fds
をそのファイル記述子(printf ... >&$fd
)に送信します。
結果は次のとおりです。
$ /tmp/test.sh
hello
master: hello
manager[0:8876]: hello
manager[1:8877]: hello
manager[4:8880]: hello
manager[2:8878]: hello
manager[3:8879]: hello
world
master: world
manager[0:8876]: world
manager[1:8877]: world
manager[3:8879]: world
manager[2:8878]: world
manager[4:8880]: world
hello
合計はどこに入力しますかworld
?