为什么 wait 不能用于命名管道中的 reader 进程?

Why wait can't work for reader process in a named pipe?

bash中的

wait是进程更改state.In下面的bash脚本,创建命名管道,并开启5个进程写入数据流,并打开 1 个进程以将数据流从中读取到其他文件中。

cat pipe.sh
fifo_file=fifo.pipe
mkfifo $fifo_file
exec 6<>$fifo_file
rm $fifo_file

DateWrite ()
{
    i=0
    while [[ $i -lt 200 ]]
    do
        str=`date`
        i=$(( i+1 ))
        echo "$i $str"
    done
}

writers=()
for  (( i=0; i<5; i++ ))
do 
    DateWrite >&6  & 
    echo "add a writer process pid  $!"
    writers+=($!)
done


while read date_time
do
    echo $date_time >> output.file 
done  <&6  &
reader=$!

for writer in "${writers[@]}" 
do
    wait "$writer"
    echo "the status of writer process pid $writer changed"   
done

echo "reader process pid is $reader"
wait  "$reader"
echo "the status of reader process pid $reader changed"   

exec 6<&-

bash pipe.sh检查pipe.sh中的等待命令。

add a writer process pid  4749
add a writer process pid  4750
add a writer process pid  4751
add a writer process pid  4752
add a writer process pid  4753
the status of writer process pid 4749 changed
the status of writer process pid 4750 changed
the status of writer process pid 4751 changed
the status of writer process pid 4752 changed
the status of writer process pid 4753 changed
reader process pid is 4754

信息列表不包含

the status of reader process pid 4754 changed

语句wait "$reader"在一个无限循环中执行,wait不能执行是正常的。
如果我删除拖线:

wait  "$reader"
echo "the status of reader process pid $reader changed"   

并执行 bash pipe.sh :

add a writer process pid  19670
add a writer process pid  19671
add a writer process pid  19673
add a writer process pid  19674
add a writer process pid  19675
the status of writer process pid 19670 changed
the status of writer process pid 19671 changed
the status of writer process pid 19673 changed
the status of writer process pid 19674 changed
the status of writer process pid 19675 changed
reader process pid is 19676

在控制台中搜索 pid 19676。

ps aux |grep '[p]ipe'
debian   19676  0.0  0.0  16516  2100 pts/1    S    19:54   0:00 bash pipe.sh

pipe.sh中创建的reader进程在pipe.sh完成后仍然是运行。
我不想在 pipe.sh.
中将 wait "$reader" 更改为 kill "$reader" 有没有办法知道 echo $date_time 已经读取了管道的末尾,并发送一个信号来关闭读取进程?

@Philippe 和这里​​的所有朋友,sleep 1; echo q >&6,也许时间间隔是这样的short.Let假设更复杂的情况:

while read date_time
do
    test "$date_time" = q && exit
    echo $date_time >> output.file 
    bash_some_code_do_some_thing
done  <&6  &

bash_some_code_do_some_thing的运行时间超过10秒,最少10秒,最多不超过10秒,无法准确估计time.You可以'不要写

这样的代码
sleep 10; echo q >&6

睡眠 100; echo q >&6 #如果 运行 时间多 200 秒怎么办?

那怎么破案呢?

无法将 EOF 发送到以读写方式打开的管道。 一种解决方法是发送退出命令:

fifo_file=fifo.pipe
mkfifo $fifo_file
exec 6<>$fifo_file
rm $fifo_file

DateWrite ()
{
    i=0
    while [[ $i -lt 200 ]]
    do
        str=`date`
        i=$(( i+1 ))
        echo "$i $str"
    done
}

writers=()
for  (( i=0; i<5; i++ ))
do 
    DateWrite >&6  & 
    echo "add a writer process pid  $!"
    writers+=($!)
done


while read date_time
do
    test "$date_time" = q && exit
    echo $date_time >> output.file 
done  <&6  &
reader=$!

for writer in "${writers[@]}" 
do
    wait "$writer"
    echo "the status of writer process pid $writer changed"   
done

echo "reader process pid is $reader"
sleep 1; echo q >&6
wait  "$reader"
echo "the status of reader process pid $reader changed"   

exec 6<&-

另一种方法是将 TERM 信号发送到 reader。