[英]While loop (in a background process) reading from file descriptor does not exit
我将首先解释我的问题陈述。 我有一个command1,它在stderr和stdout上生成数据,stderr通过管道传输到command2,而stderr应该go到一个后台进程,该进程不断调用API。
相同的虚拟示例:
#!/bin/bash
set -e;
metric_background_process () {
# This while loop waits till there is a line to read
while read -u 3 -r line; do
echo $line;
done;
# This never prints !!!
echo "Done"
}
tmp_dir=$(mktemp -d)
mkfifo "$tmp_dir/f1"
# Allocate a file descriptor to the named pipe
# to allow read and write from it.
exec 3<> "$tmp_dir/f1"
metric_background_process <&3 &
pid=$!
# Main commands (stdout is being piped to stderr as a dummy case)
cat ./assets/random_file 1>&3
exec 3<&-
wait $pid
输入文件包含:1 到 9,其中 9 是最后一行。
观察到 Output:
1
2
3
4
5
6
7
8
shell 打印8
后等待, 9
不打印,程序不会自行停止。
无论我尝试什么, while
循环都不会退出。 也许我错过了一些简单的东西,任何帮助或进一步的澄清问题将不胜感激。
父 shell 正在打开 fifo 以进行读/写 ( <>
)。 子shell ( &
) 继承了 FD,因此它也打开了 fifo 以进行读/写。 当父级关闭 FD 时,子外壳仍在打开 fifo 进行写入,因此写入端永远不会关闭,因此读取端( read -u 3
)无法获得EOF
。
为了让它更简单一点——
剧本:
$ cat foo.sh
metric_background_process () {
local fifo=$1
while read line; do
echo $line
done < $fifo
echo "Done"
}
tmp_dir=$(mktemp -d)
fifo="$tmp_dir/f1"
mkfifo "$tmp_dir/f1"
metric_background_process $fifo &
pid=$!
exec 3> $fifo
for i in {1..5}; do
echo i=$i >&3
done
exec 3>&-
wait $pid
结果:
$ bash foo.sh
i=1
i=2
i=3
i=4
i=5
Done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.