web-dev-qa-db-ja.com

トラップ関数をコメントアウトすると、control-cが機能するのはなぜですか?

Rhel VMを立ち上げた後、ログファイル(tail -f xyz.log)をテーリングしていましたが、control-cが機能して終了しないことに気付きました。control-を試しました。 zは実行しましたが、バックグラウンドジョブが残ったため、プロセスを手動で強制終了する必要がありました(tail -f xyz.log)。

私の店の誰かが、私が行った/ etc/profileのトラップ機能をコメントアウトするように私に言いました。

#trap "" 1 2 3 15

次に、ログアウトしてシェル環境に再度ログインすると、control-cが機能し始めました。

何が起こったのかを理解したいだけです。私は「マントラップ」をしましたが、残念ながら内容をうまく消費していません。これを読んでいただきありがとうございます。

2
DaeYoung

指定されたtrapコマンドは、これらの信号を傍受するようにシェルに指示しました。

1 SIGHUP
2SIGINT
3SIGQUIT
15SIGTERM

「」は、これらの信号の1つが受信された場合に実行されるコマンドです。言い換えれば、何もしません。信号を完全に無視します。

stty -aを使用して、どの文字が信号にバインドされているかを確認できます。たとえば、この例のsttyからの出力の2行目(形式は使用しているシステムによって異なります):

$ stty -a
speed 38400 baud; rows 40; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

一部の文字と信号の対応は 11.1.9特殊文字 で与えられます。例:

  • intr送信SIGINT
  • quit送信SIGQUIT

したがって、私の^CSIGINTを送信します(構成が異なる場合があります)。

trapをコメントアウトすると、シェルはデフォルトの動作に戻ります。これにより、入力時にこれらの特殊文字がシグナルを送信します。たとえば、^\ sendSIGQUITおよび^CSIGINTを送信します。

参考文献:

3
Thomas Dickey

押す Ctrl+C ターミナルでは、SIGINT signal をターミナルで実行されているプロセスに送信します。 (より正確には、フォアグラウンドプロセスグループ内のすべてのプロセスに送信されます。たとえば、foo | tail -fを実行している場合、シグナルはfootailの両方に送信されます。)

[〜#〜] sigint [〜#〜] (割り込みシグナル)の従来の意味は、「現在のタスクを中止し、対話型プロンプトに戻る」です。テールなどのインタラクティブなプロンプトがないプログラムは、単に終了してシェルに引き継がせます。

trap command は、シグナルを受信したときのシェルの動作を定義します。たとえば、trap 'echo killed' INTは、SIGINTシグナルを受信すると、シェルにkilledを出力させます。 trap 'echo killed' 2は、名前がINTである信号の番号であるため、LinuxPCでも同じです。これは、シェルがシグナルを受信した場合にのみトリガーされ、別のプログラムがフォアグラウンドにある場合はトリガーされません。

trap "" INTは特殊なケースです。シグナルを受信したときに何もしないようにシェルに指示するだけでなく、シグナルを無視するようにシェルに指示します。プロセスがシグナルのハンドラーを登録する場合、それは実行するプログラムには影響しません。ハンドラーはプロセス内のコードであるため、別のプログラムから呼び出す方法はありません。ただし、シグナルを無視することは別の設定であり、プログラムが別のプログラムを実行するときにそのシグナルが保持されます。したがって、trap "" INTの後、tailを実行すると、シグナルは無視され、を押します。 Ctrl+C 効果はありません。

シェル内のシグナルを効果的に無視し続けたいが、起動するプログラムでは無視したくない場合は、空でないトラップを設定します。たとえば、trap " " INTまたはtrap : INT:はシェルのno-です。 opコマンド)。または、tailを実行する前にtrap - INTを実行して、シグナル処理をデフォルトの無視されない状態にリセットします。

trapはシェル組み込みであり、通常の形式はtrap cmd list_of_signals。あなたの場合、cmdは空です。つまり、そのシグナルを無視します。 1hangupシグナル、3intrまたはCtrl-C。見る man bash セクション Shell Builtin Commands詳細については。

0
ott--