名前付きパイプと通信する2つのプロセスを並行して実行しました。奇妙な動作に気付きました: すべての書き込みの後に読み取りが続くか、またはその逆でなければなりません! ルールを破ると、プログラムがハングし、ctrl+C で終了すると、子プロセスはハングし、再読み込みができなくなります。
私の例:
#!/bin/bash
shopt -u failglob
shopt -s extglob nullglob dotglob
function london (){
local message answer fifo id return exitcode
fifo=fifo_$RANDOM.$RANDOM.$RANDOM.$$
mkfifo ${fifo}
#trap 'rm -rf "$fifo"' EXIT
( berlin $fifo ) &
id=$!
echo "parent id: $$, child id: $id"
message='Greetings from London!(1)'
echo "$message" > $fifo
echo "1. parent sent it's 1st message"
#*****write-to-write error!*****#
message='Greetings from London!(2)'
#read -r answer < $fifo
echo "$message" > $fifo
echo "2. parent sent it's 2nd message"
wait
rm -rf $fifo
}
function berlin (){
local message answer fifo
fifo=$1
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
#*****read-to-read error!*****#
#echo 'next' > $fifo
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
}
london
「write-to-write」または「read-to-read」メッセージを挿入したポイントの下に、問題を解決する2つのコメント行があり、上記のルールが不思議なことに成り立っていると思います!!! 何が起こっているのですか?
出力は次のとおりです。
parent id: 4921, child id: 4923
1. parent sent it's 1st message
2. parent sent it's 2nd message
Berlin says:> Greetings from London!(1)
ありがとう!
これですべてが明確になり、「読者の側からパイプを開いたままにしてください」という一言に凝縮されたと思います。
ここで、ループ内のコマンドの「一部」に 2 番目の入力ファイル記述子を追加したいとします。これどうやってするの?これが私の新しいベルリン関数です。
function berlin (){
local message answer fifo
fifo=$1
while true; do
read -r answer
echo 'Berlin says:> '"$answer"
#this fails!
read -r -p "reading from fd0: " <&0
if [[ $answer = 'quit' ]]; then
break
fi
done < "$fifo" 3>"$fifo"
}
ご覧のとおり、パイプにはファイル記述子 3 を使用しますが、fd 0 から読み取ろうとすると、実際には fd 3 から読み取られます! これを達成する方法はありますか?