4

私はまだ bash スクリプトにかなり慣れていないため、この単純なトラップが期待どおりに機能しない理由を理解するのに苦労しています。

目標CTRL- +を押してスキップできるオプションの待機期間を作成しますC

CTRL+ -を押したときの期待される結果Cすぐに「昼寝する時間がありません!」と反響します。そして終了します。

CTRL+ -を押した実際の結果は、Cすぐに "naptime over" をエコーし​​ます。そして終了します。

#!/bin/bash

nonap() {
    echo "No time for napping!"
    exit
}

trap nonap INT

echo "Sleeping for 5 seconds, hit ctrl-c to proceed now."
sleep 5 
echo "Naptime over."

トラップ関数が呼び出されないのはなぜですか?

4

1 に答える 1

4

(bash 3.2.25を使用した古代のRHEL Linuxで)試してみたところ、コードを保存して実行しtrap.shbash trap.sh次のようになりました。

 Sleeping for 5 seconds, hit ctrl-c to proceed now.

に続く:

No time for napping!

あなたが期待したように、私が中断したとき。中断せずに実行すると、予想されるメッセージが表示されました。

Naptime over.

その後、次のようにコメントしました。

少なくとも、期待どおりに動作するはずです。Tinycore Linux の最新バージョンと GNU bash、バージョン 4.0.33(1)-release (i686-pc-linux-gnu) を使用しています。新しいターミナルを開くdeclare -f nonapと、trapどちらも出力を返しません。このスクリプトを実行して「Naptime over」を取得した後。私のスクリプトで定義されているように、出力、trap戻りtrap -- 'nonap' SIGINT、および関数を返します。declare -f nonap

私は次のように答えました。

では、このスクリプトをどのように実行していますか? それを使用するsourceか、それ.を読むために?ああ、そうです。あなたがする必要があります。私はちょうどそれを試してみました.ソーシング中の割り込みは私に与えましたNaptime over.; ただし、別の割り込みを入力するNo time for napping!と、シェルが終了しました。2 回目は期待どおりに動作しました。スクリプトに点を打っている間、割り込みがどうなっているのかわかりません。それは予期しない動作です。

なぜあなたはこれをソーシングまたはドットにしたいと思ったのですか? 普通の古いスクリプトとして使用してみませんか?

入手する理由はありません...私はそれを使用してテスト中に実行していました。を使用しているときに、このような異常に遭遇したことはないと思います。前ですが、私もまだ初心者です。私はあなたと同じ結果を見ています.bashで実行すると、最初の割り込みで期待どおりに動作します.

さて、次のアドバイスには「先生、先生、頭を壁にぶつけると痛い」という要素がありますが、そこには基本的な実用主義もあります。

source(C シェルまたはbash) または.(Bourne、Korn、POSIX シェルまたは) を使用bashして、スクリプトをサブシェルとして実行するのではなく、呼び出しシェルの環境に影響を与えます。問題を解決するための特典 (主にまぐれによるものではありますが) は、スクリプトを実行した後、関数が定義されていることを報告したときでした。を使用していない限り、それは起こり得ませんsourcetrapこの場合、呼び出し元のシェルでセットが必要ないことは明らかです。(kshwith promptからToru JL:)実行すると、次のようになりました。

Toru JL: bash
bash-3.2$ trap
bash-3.2$ source trap.sh
Sleeping for 5 seconds, hit ctrl-c to proceed now.

Naptime over.
bash-3.2$ trap
trap -- 'nonap' INT
bash-3.2$ No time for napping!
Toru JL: 

「昼寝している暇はない!」もう一度割り込みキーを押すと、メッセージが表示され、bashI'd run が終了しました。で引き続き使用する場合は、スクリプトの末尾sourceに追加trap INTしたり、関数を未定義にしたりすることもできます。

ただし、シェルですべてを分離し、サブプロセスとして実行する方がはるかに優れていると思います。

しかし...スクリプトがソースである場合、この種のものが面白いゲームをプレイするというあなたの発見は興味深いものです. の動作の軽微な異常ですbash。「バグ」のレベルまで上がるかどうかはわかりません。「バグ」と主張する前に、かなり慎重に(おそらく数回)多くのマニュアルを読み、他の知識のある人に相談する必要があります。

それが慰めになるかどうかはわかりませんがksh、あなたのスクリプトを試して.みたところ、両方が期待どおりに機能しました。

Toru JL: ksh
$ . trap.sh
Sleeping for 5 seconds, hit ctrl-c to proceed now.
No time for napping!
Toru JL: 
于 2012-05-17T06:03:10.687 に答える