Signals
在寫入 FIFO 時擷取 SIGPIPE
這些是重現問題的步驟。
writer
:#!/bin/bash trap 'echo NoReader!' PIPE cat > fifo
打開兩個終端。我將用下面的
>T1<
和>T2<
標題來表示它們,用 . 來表示它們的提示$
。>T1< $ mkfifo fifo $ bash writer ABC >T2< $ cat fifo ABC ^C >T1< DEF $ echo $? 141
從
man fifo
,當一個程序嘗試寫入另一端未打開以供讀取的 FIFO 時,會向該程序發送一個 SIGPIPE 信號。
在我進入的時候
DEF
,FIFO 已經沒有讀卡器了。所以我希望在進入後觸發SIGPIPE上的陷阱DEF
以及相應的NoReader!
消息。相反,該過程會靜默終止。錯誤程式碼是141,這表明它確實被 SIGPIPE 終止。另一方面,執行這個**
newWriter
**#!/bin/bash trap 'echo NoReader!' PIPE var=$(head -c 100000 /dev/urandom) echo "$var" > fifo
在 1 號航站樓和2 號
head -c 1 fifo
航站樓確實觸發了陷阱!但是,如果我只是從 urandom 中提取 1000 個字節而不是 100000 個字節,則不會觸發陷阱。我錯過了什麼?為什麼在第一個
writer
範例中沒有觸發陷阱,而是在newWriter
100000 字節(而不是 1000 字節)中?
貓
不執行陷阱處理程序的原因
bash
僅僅是bash
沒有接收到該信號。它僅被發送到寫入過程,即cat
.如果執行寫入的是 shell 本身,則執行陷阱處理程序:
#!/bin/bash exec 3>fifo trap 'echo NoReader!' PIPE while IFS= read -r -d '' -n 1 input; do printf %s "$input" >&3 || break done </dev/urandom
頭
strace
顯示了head
呼叫不同行為的原因:FIFO 緩衝 4096 字節(在我的系統上;可以從核心中檢索到這個值)。所以你不應該得到一個錯誤-c 4096
但是4097
。