「${FUNCNAME [@]}」のSIGINTは消去されませんでした。

「${FUNCNAME [@]}」のSIGINTは消去されませんでした。

以下のようにキーボード入力Ctrl+割り込みで次のスクリプトを使用します。C

$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a source

while 関数を複数回繰り返すと、SIGINT次のようなシナリオが生成されます。a

...

$ a
Performing
^C
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a a a a a a a a a source

この問題を説明するために、次のように定義された関数を提供するb他の関数を試してみましょう。message_error

$ function message_error() {
>   local MESSAGE="$1"
>
>   # FUNCNAME[1], as [0] is `message_error`, gets the calling function
>   echo "[[ ERROR ]] ${FUNCNAME[1]}: $MESSAGE"
>   echo "Rest of the stack: ${FUNCNAME[@]}"
>}
$ function b() { message_error "Oh no"; }
$ b
[[ ERROR ]] b: Oh no
Rest of the stack: message_error b a a a a a a a a a source

sourceで関数が呼び出されても、a呼び出し関数として表示されます。ご覧のとおり、これらのa機能はすべて終了しました。しかし、それでもFUNCNAME配列には残ります。

なぜこれですか?削除失敗後にSIGINTを削除する方法は?~/.bash_functionsすべての関数は複数の共通関数から派生し、その関数を取得するとSIGINTの解釈方法に影響します。

答え1

なぜならFUNCNAME読み取り専用アイテムを削除できない配列です。これはうまくいくようですが、特別なFUNCNAMEアクションunset FUNCNAMEも中断します。bash

FUNCNAME次の方法を使用してスパムを防ぐことができますtrap

$ trap : SIGINT
$ function a() {  echo "Performing"; sleep 10; echo "Performed"; } 
$ a
Performing
^C
$ echo %"${FUNCNAME[@]}"%
%%

上記の予防措置を無効にするには、次の手順を実行しますtrap - SIGINT

関連情報