簡體   English   中英

為什么陷阱在管道中不起作用

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

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