Zsh

如何在 Zsh 中無條件地擷取 EXIT(即使被中斷)?

  • October 19, 2020

我想擷取一個函式的退出鉤子。Bash 提供了一個很好的信號,稱為RETURN(非 POSIX),它在函式返回時被呼叫,例如

function test_trap() {
   trap 'echo trapped' RETURN
   sleep 10  # simulate time-consuming commands
   echo done
}

當函式返回時,我看到“被困”,即使我發送一個SIGINTwithCtrl C。Zsh 有類似的功能嗎?我在 Zsh 中嘗試EXIT過,但它只擷取正常返回,而不是當我用SIGINT. 我還嘗試使用相同的鉤子函式擷取兩者 EXITINT但它有兩個問題:

  1. 當我中斷鉤子表達式時,它會被計算兩次。沒什麼大不了; 我的鉤子表達式恰好是冪等的。
  2. Zsh 中的EXIT是本地的:從函式返回時,恢復原來的鉤子。這類似於局部變數如何遮蔽全域變數。不幸的是,INT鉤子總是全域的,所以我指定的任何鉤子都會覆蓋全域鉤子。我需要記住原來的INT鉤子,然後再恢復它。正確地做到這一點非常棘手;我可以試試這個。

這就像函式之外的 EXIT 陷阱。退出和被殺是兩件不同的事情。

所以就像在函式之外,你需要單獨處理它們:

test_trap() {
 set -o localoptions -o localtraps
 trap 'echo "I am exiting."' EXIT
 trap 'echo "I have been interrupted, so"; return 1' INT

 echo start
 sleep 10
 echo end
}

test_trap
echo "returned with: $?"

這使:

$ zsh ./that-script
start
^CI have been interrupted, so
I am exiting.
returned with: 1

如果您希望shell(不僅僅是函式)在處理執行函式時收到的 SIGINT 信號時退出,如果您想通過以下方式報告您的死亡,請替換return 1exit(或在恢復預設處理程序(trap - INT; kill -s INT "$$"信號給你的父母)。

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