[英]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.