为什么 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。
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。