簡體   English   中英

從文件描述符讀取的循環(在后台進程中)不退出

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM