[英]Why trap didn't work in a pipeline
在這個腳本中我們有一個腳本trap.sh
#!/bin/bash
trap "echo trapped" EXIT
exit 0
和test.sh. 如果test.sh是這樣的
#!/bin/bash
. trap.sh
要么
#!/bin/bash
./trap.sh | :
陷阱工作
但是如果test.sh是這樣的話
#!/bin/bash
. trap.sh | :
陷阱不起作用。
誰知道為什么會這樣?
更好地將測試命令更改為. trap.sh|cat
. trap.sh|cat
(從標准輸出trap.sh
無法與顯示:
)。 但即便如此也沒有輸出,所以你是對的:陷阱不起作用。 這必須是bash中的錯誤,應該向維護者報告。
有趣的是,當我們從腳本trap.sh內部echo $$
時,我們看到它由執行整個管道的同一個shell執行. trap.sh|cat
. trap.sh|cat
,與手冊的語句相矛盾: 管道中的每個命令都作為一個單獨的進程執行(即,在子shell中)。 這是一個謬論,請參閱評論。 也許這與最小化子shell創建的一些優化有關,但這只是推測。
我修改了trap.sh
以包含xtrace
選項。
#!/bin/bash
set -x
trap 'echo trapped' EXIT
exit 0
運行trap.sh
作為腳本生成
〜$ ./trap.sh | 貓+陷阱'回聲被困'出口+退出0 +被困陷阱被困
然而,首先采購它
~ $ . trap.sh | cat
++ trap 'echo trapped' EXIT
++ exit 0
這表明trap
是在更深的子shell中執行的(為什么,我不知道),並且陷阱本身永遠不會被執行(我在第二個實驗中通過touch
陷阱中的文件而不是僅僅回顯來確認有一個問題,標准輸出被繼承;文件從未被觸及)。
我的猜測是,在執行source
命令之前,以某種方式忽略EXIT
信號,基於手冊頁中trap
命令描述中的這句話:
進入shell時忽略的信號不能被捕獲或重置。
因此,執行trap
命令,但陷阱本身從未注冊,因此不會觸發。
管道左側的命令在子shell中運行:
exit | grep
退出sigtrap似乎不會傳播到子shell。
trap 'echo T >&2' EXIT ; (exit) # Nothing.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.