Zshで(中断されても)無条件にEXITをキャッチする方法は?

Zshで(中断されても)無条件にEXITをキャッチする方法は?

関数の終了フックをキャプチャしたいと思います。 Bashは、RETURN関数が返されたときに呼び出される(POSIXではなく)という素晴らしい信号を提供します。

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

関数が返されると「Trapped」と表示されます。SIGINTメールを送ってもCtrl C。 Zshにも同様の機能がありますか? Zshで試してみましたEXITが、Interruptを使用するときではなく、一般的な戻り値だけをキャッチしますSIGINT。トラップも試しました。両方 EXITINT同じフック機能がありますが、2つの問題があります。

  1. 中断すると、フック式が2回評価されます。あまりありません。私のフックの表現は冪等性を持っています。
  2. ZshにあるのはEXIT基本です。関数から返されると、元のフックが復元されます。これは、ローカル変数がグローバル変数を隠す方法と似ています。残念ながら、INTフックは常にグローバルなので、私が指定するすべてのフックはグローバルフックをオーバーライドします。元INTのフックを覚えて後で復元する必要があります。これを正しく行うのは非常に面倒です。代わりにこれを試してみることもできます。

ベストアンサー1

これは関数外の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

欲しいならシェル(関数だけではありません)関数の実行中にハンドルSIGINTシグナルを受け取ったら終了し、シグナルを介して親に死亡を報告するには、代わりに(またはデフォルトハンドラ()を復元してからSIGINTで自殺)return 1exit置き換えます。trap - INT; kill -s INT "$$"

おすすめ記事