以下のようにキーボード入力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
。