Ctrl-Cがkill -2と異なる動作をする理由

Ctrl-Cがkill -2と異なる動作をする理由

SIGINTを処理して正常に終了するようになっているプログラムがあります。このプログラムをバックグラウンドで実行せずに端末で実行する場合は、Ctrl-C を使用してプログラムを閉じることができます。ログを確認すると、すべてが期待どおりに機能していることがわかります。

別の端末を開いて呼び出すと、kill -2 [pid]何もkill -s INT [pid]しません。ログには何も表示されず、プログラムを起動した端末でCtrl-Cを押すまで、プログラムは通常どおり実行され続けます。

Ctrl-Cがシグナルを送信する方法とKillがシグナルを送信する方法の違いはありますか?

追加の詳細:

CLASSPATHこのプログラムは、いくつかの環境変数(たとえば)を設定してjava [main class]Ctrl-Zを押し、ps次のように結果を実行するbashシェルスクリプトによって起動されるJavaアプリケーションです。

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
mdeck    10251 10250  0 11:48 pts/2    00:00:00 -bash
mdeck    13405 10251  0 18:12 pts/2    00:00:00 /bin/bash /usr/local/bin/myapp.sh
mdeck    13509 13405 25 18:12 pts/2    00:00:03 java com.company.MyApp
mdeck    13526 10251  0 18:13 pts/2    00:00:00 ps -f

Gillesが要求したstty出力は次のとおりです。

$ stty -a </dev/pts/2
speed 38400 baud; rows 40; columns 203; line = 0;
intr = ^C; quit = ^\; erase = ^?; 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

ベストアンサー1

1つの可能性は、プログラムがCtrl+Cシーケンスをキャプチャすることです。stty -aの出力を確認してください。このintr設定は、SIGINT信号を送信するキーの組み合わせ(存在する場合)を示し、isig信号キーが有効になっているか(-isig無効になっていることを意味します)を示します。

プログラムが複数のプロセスで構成されている場合は、Ctrl+ を押してCプロセスのすべてのプロセスに SIGINT を送信します。プロセスグループ。プロセスの1つではなく、プロセスグループにシグナルを送信しても同じ効果が得られます。プロセスグループにシグナルを送信するには、まずそのリーダーを決定します。これは、他のすべてのプロセスを開始する最初のプロセスです。プロセスグループをバックグラウンドで実行すると、PIDが表示されますjobs -l。プロセスグループリーダーのPIDはPGID(プロセスグループID)です。信号をカソード端子に送信します。たとえば、PGIDが1234の場合kill -INT -1234

プログラムがラッパースクリプトと基本アプリケーションで構成されている場合は、考慮すべき2つのシナリオがあります。基本アプリケーションが終了した後にラッパースクリプトがすぐに終了するようにクリーンアップが必要ない場合は、ラッパースクリプト呼び出しを実行しますexec

#!/bin/sh
export SOMEVAR=somevalue
exec /path/to/application "$@"

このようにして、アプリケーションはスクリプトを置き換え、そのPIDを継承できます。一部のシェルは他のプログラムで終わるスクリプトを実行するように最適化されていますが、すべてではありません。この方法は、スクリプトがいくつかのクリーンアップ(一時ファイルの削除など)を実行する必要がある場合は機能しません。

スクリプトがシグナルを検出してアプリケーションに送信することを検討してください。全体のプロセスの概要は次のとおりです。

/path/to/application "$@" &
app_pid=$!
trap -INT 'kill -INT $app_pid'
wait $!
rm /temp/file

おすすめ記事