Bash

“trap … INT TERM EXIT”真的有必要嗎?

  • December 12, 2021

許多trap用於trap ... INT TERM EXIT清理任務的範例。但是真的有必要列出所有三個 sigspecs 嗎?

手冊說

如果 SIGNAL_SPEC 為 EXIT (0),則在退出 shell 時執行 ARG。

我相信這適用於腳本是否正常完成或因為它收到SIGINT或而完成SIGTERM。一個實驗也證實了我的信念:

$ cat ./trap-exit
#!/bin/bash
trap 'echo TRAP' EXIT
sleep 3
$ ./trap-exit & sleep 1; kill -INT %1
[1] 759
TRAP
[1]+  Interrupt               ./trap-exit
$ ./trap-exit & sleep 1; kill -TERM %1
[1] 773
TRAP
[1]+  Terminated              ./trap-exit

那為什麼這麼多例子都列出來了INT TERM EXIT?還是我錯過了什麼,有沒有鞋底EXIT會錯過的情況?

POSIX 規範沒有說明導致執行 EXIT 陷阱的條件,只說明了執行時它的環境必須是什麼樣子。

在 Busybox 的 ash shell 中,由於 SIGINT 或 SIGTERM,您的陷阱退出測試在退出之前不會回顯“陷阱”。我懷疑存在其他可能無法以這種方式工作的外殼。

# /tmp/test.sh & sleep 1; kill -INT %1
# 
[1]+  Interrupt                  /tmp/test.sh
# 
# 
# /tmp/test.sh & sleep 1; kill -TERM %1
# 
[1]+  Terminated                 /tmp/test.sh
# 

是,有一點不同。

該腳本將在您按下時退出Enter,或發送它SIGINTSIGTERM

trap '' EXIT
echo ' --- press ENTER to close --- '
read response

當您按下時,此腳本將退出Enter

trap '' EXIT INT TERM
echo ' --- press ENTER to close --- '
read response
  • shBashZsh中測試。(當您添加命令以執行陷阱時,不再在sh中工作)

@Shawn 也說過:AshDash不會使用EXIT.

因此,要穩健地處理信號,最好EXIT完全避免陷入陷阱,並使用以下內容:

cleanup() {
   echo "Cleaning stuff up..."
   exit
}

trap cleanup INT TERM
echo ' --- press ENTER to close --- '
read var
cleanup

引用自:https://unix.stackexchange.com/questions/57940