1.

1.

理解する

Bashがコマンドが完了するのを待つ場合トラップが確立されたことを知らせると、コマンドが完了するまでトラップは実行されません。

Bashがwait組み込み関数を介して非同期コマンドを待つ場合、トラップを設定した信号を受信すると、内蔵待機が128より大きい終了状態に即座に返され、すぐにトラップが実行されます。

Bashのマニュアルによると、次のコマンドを実行します。

  1. どちらの例でも、SIGINT(Ctrl-Cで送信)は、フォアグラウンドジョブ(引用符の最初のケース)とバックグラウンドジョブ(引用符の2番目のケース)が完了するのを待たずにすぐに終了します。

    引用の最初の文は、Bashがフォアグラウンドジョブを実行してsignalを受け取ると、コマンドが完了するまで信号のトラップがSIGINT設定 されたSIGINT後に実行されることを意味しますか?の場合、最初の例では、ctrl-Cフォアグラウンド操作が完了する直前に存在するのはなぜですか?

    $ sleep 10000  # a foreground job
    ^C
    
    
    $ sleep 10000 & # a background job
    [1] 21219
    $ wait 21219
    ^C
    $ echo $?
    130
    
  2. 何ですか「トラップが設置されたというシグナル」 意味は、

    • arg指定されたトラップを通過した信号trap arg sigspecまたは

    • 無視されない信号、または

    • トラップはデフォルトのトラップではないシグナルですか?

    Part 1の例では、SIGINTのトラップを設定していないため、シグナルにデフォルトハンドラ(実行ループが中断)がありました。は 基本ハンドラを使用した信号これは罠を設置したと見なされますか?

  3. 罠を設置しました。SIGINTただし、ctrl-C完了する前に次のコマンドは終了します。それでは、これは私が引用した最初の文と反対ですか?

    $ trap "echo You hit control-C!" INT
    $ bash -c 'sleep 10; echo "$?"'
    ^C
    $
    

    トラップを設置する前にSIGINTまた、 ctrl-C完了する前に同じコマンドが終了します。それでは、これは私が引用した最初の文と反対ですか?

    $ bash -c 'sleep 10; echo "$?"'
    ^C
    
  4. 引用の2つの文が何を意味するのかを説明するために、いくつかの例を挙げることができますか?

ありがとうございます。

ベストアンサー1

「閉じ込められた信号」とはどういう意味ですか?

これは、ハンドラコードが空でない場合(を使用して)定義されたハンドラを持つ信号です。trap 'handling code' SIGこれにより信号は無視されます。

したがって、基本構成の信号はトラップされた信号ではありません。投稿の引用の一部は、基本設定のシグナルにも適用されます。トラップを実行する、トラップが定義されていないからです。


マニュアルでは、シグナル伝達について説明します。皮をむく、そのシェルで実行するコマンドではありません。

1.

Bashがコマンドが完了するのを待つ場合トラップが確立されたことを知らせると、コマンドが完了するまでトラップは実行されません。

(1)

最初の例では、ctrl-Cがフォアグラウンド操作を完了する直前に終了するのはなぜですか?

sleep 10対話型シェルのプロンプトで実行されている場合、シェルは仕事を展望ioctl()ttyデバイスのプロセスグループを介して、どのプロセスグループが前景プロセスグループであるかをターミナルラインルールに通知します)SIGINT のみsleep受信され、^C対話型シェルは受信されません。したがって、この動作をテストすることは役に立ちません。

  • 親シェルは対話型であるため、そのプロセスはフォアグラウンドプロセスグループに属していないため、SIGINTを受け取りません。

  • 各コマンドは必要に応じて信号を処理できます。sleepSIGINTに対して特別な操作は行われないため、起動時にSIGINTが無視されない限り、基本構成(終了)が取得されます。

(2)sleep 10非対話型シェルで実行している場合

bash -c 'sleep 10; echo "$?"'

bash非対話型シェルとシェルの両方がCtrl-Cを押すとsleepSIGINTを受け取ります。

bashすぐに終了すると、sleepSIGINT信号を無視または処理すると、バックグラウンドでコマンドが無人状態で実行される可能性があります。だから代わりに

  • bash他のほとんどの殻と同様に、彫刻コマンドを待っている間に信号(少なくともいくつかの信号)を受信します。
  • コマンドが終了すると、転送は再開されます(実行トラップ)。これはまた、トラップ内の命令が他の命令と同時に実行されるのを防止する。

上記の例ではsleepSIGINTが終了するため、bash独自のSIGINTを処理するのに時間がかかりません(ここではtrapSIGINTを追加していないため終了します)。

(3)非対話型シェルを実行するときは、Ctrl + Cを押します。

bash -c 'sh -c "trap \"\" INT; sleep 3"; echo "$?"'

trapSIGINTなし)bashSIGINTによって終了しません。bash、他のシェルと同様に、SIGINTとSIGQUITを具体的に処理します。彼らは実装待ってから協力して終了してください。で説明されている行動https://www.cons.org/cracauer/sigint.html(少し迷惑を引き起こすことが知られています。SIGINT処理コマンドを呼び出すスクリプトは中断できません。^C)

(4) 正しくテストするには、次のことを行う必要があります。非対話型で実行bashそれSIGINT トラップセットそして電話してくださいSIGINT直後に終了しないコマンド良い:

bash -c 'trap "echo Ouch" INT; sh -c "trap \"\" INT; sleep 3"'

bashsh(同様に)SIGINTを待つことはsleep無視されるので、SIGINTはどちらもtrap "" INT終了しません。 SIGINTは無視されませんが、返されるまで処理が遅れます。表示される画面はオンになっているのではなく、通常の終了後に表示されます。sleepshbashshOuchCtrl+Csleepsh

このtrapコマンドは、実行される同じシェルの信号トラップを設定します。したがって、trap非対話型シェルの外部と親シェル内でコマンドを実行すると、

$ trap "echo You hit control-C!" INT
$ bash -c 'sleep 10; echo "$?"'
^C
$

これは非対話型bashであり、sleepコマンドはtrap親シェルから継承されません。他のコマンドが実行されると、シグナルハンドラが失われます(ハンドラexecve()コードを含むプロセスのアドレス空間全体が消去されます)。execve()定義されたハンドラを持つ信号がデフォルト設定に復元されると、無視された信号は無視されたままになります。また、ほとんどのシェルでは、trapsはサブシェルでもリセットされます。

2.

Bashがwait組み込み関数を介して非同期コマンドを待つ場合、トラップを設定した信号を受信すると、内蔵待機が128より大きい終了状態に即座に返され、すぐにトラップが実行されます。

wait明示的に使用する場合wait 閉じ込められた信号(そして明らかにシェルを完全に殺す信号)によって中断されます。

これが難しくなるキャプチャ信号があるときにコマンドの終了状態を確実に取得します。:

$ bash -c 'trap "echo Ouch" INT; sh -c "trap \"\" INT; sleep 10" & wait "$!"; echo "$?"'
^COuch
130

この場合、SIGINTによってsleep殺されませshんでした(無視したためです)。待機中に信号(SIGINT)が受信されたため、終了ステータスは依然としてwait返されます。終了ステータスを取得するには、実際に終了するまで繰り返す必要があります。130shwait "$!"shsh

おすすめ記事