web-dev-qa-db-ja.com

プロセスを中断するのではなく、Unixで終了する

Unixコマンドラインで Ctrl-C、それはプロセスを終了しませんが、むしろそれを中断し、私はシェルプロンプトに戻ります。

したがって、次の2つの質問があります。

    1. 中断されたすべてのプロセスのリストを表示して終了する方法はありますか?
    1. プロセスを中断するのではなく終了するために押すキーの組み合わせは何ですか?
12
John

Ctrl+CSIGINTを送信します。デフォルトでは、これによりアプリケーションが終了します。

あなたはこれをと混同しています Ctrl-Z、bashでアプリケーションを一時停止します。

歴史的に、これらはキーストロークにバインドされた3つの信号がありました

  • SIGINT(割り込み)通常 Ctrl+C または Del
  • SIGQUIT-終了-通常は Ctrl+\
  • SIGSUSPサスペンド-通常は Ctrl+Z

一部の* nixフレーバーには、他の信号もバインドされています。コマンドを使用してキーボードのバインドを確認できます。

stty -a

私のシステム、OS/Xでは、これにより次の出力が生成されます

speed 9600 baud; 65 rows; 213 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

この場合のkillは、現在の入力バッファのクリアに関係するKILLシグナルではないことに注意してください。

SIGQUITを使用してプロセスを停止すると、より多くの成功を収めることができますが、プロセスがシグナルをキャッチして無視する可能性があるため、これは当てはまらない可能性があります。

プロセスが割り込みをキャッチして無視したか、プロセスが終了したため、「中断された」プロセスのリストの概念はありません。ジョブを入力すると、中断されたプロセスのリストを取得できます

7
Steve Weet

正解はたくさんありますが、完全なものはありません。

  1. 他の多くの人が言っているように:Control-Cは通常unixシグナルSIGINTを送信し、デフォルトの動作(それをオーバーライドしないプログラムから)は「プロセスの終了」です。 プログラムはこのシグナルを無視するか、必要に応じて別のアクションを実行できます。
  2. Control- \を使用してキーボードからSIGQUITを送信することもできます。ここでの違いは、デフォルトでは、プロセスがコアファイルを書き込んでから終了することです。 プログラムはこのシグナルを無視するか、必要に応じて別のアクションを実行できます。
  3. 極端な偏見を持って、プロセスを停止せずに終了するには、デフォルトでどのキーにもバインドされていないSIGKILLを使用します。代わりに、通常は kill (1) コマンドを使用して送信し、送信するシグナルを次のように指定します。

    $ kill -9 <process ID>
    

    またはニーモニック

    $ kill -KILL <process ID>
    

    このシグナルはOSによって直接処理され、プログラムはデフォルトの動作をオーバーライドできません

  4. シェルがジョブ制御をサポートしている場合は、 catwalk's answer のように%文字を使用したジョブ識別をサポートする組み込みバージョンのkillもサポートしている可能性があります。

  5. 再開可能な方法でプロセスを一時停止するには、SIGTSTPを送信するControl-zを使用します。このようなプロセスを再開するには、fgを使用して端末の制御を続行するか、bgを使用して端末の制御を維持せずに実行を設定しますただし、デフォルトでは、出力は引き続き送信されます)。

これはほとんどの端末初心者には明らかではありませんが、問題がインタラクティブプログラムを使用しているだけで、抜け出す方法がわからない場合は、qが終了することがよくあります。たとえば、これはlessを終了するためのキーです。これは、特にmanページを表示したときに取得するプログラムでもあります。

一部のプログラムには、終了するための他のキーボードショートカットがあります。 vimまたはviで、ESC:wqを使用します。 emacsで、Control-C Control-Xを使用します。 nanoまたはpicoで、Control-Xを使用します。これらの例では、特に、これらのショートカットが編集中のファイルに加えた変更を保存するかどうかに関して微妙な点があることに注意してください。

1
asmeurer
  1. バックグラウンドプロセスのリストを表示するには:jobs

    殺すため: kill %1(1をjobs出力のように対応するジョブIDに置き換えます)

  2. ここ を参照してください
1
catwalk

Ctrl-CはSIGINTを送信します。これにより、デフォルトでプロセスが終了しますが、トラップされる可能性があります(\bin shtrapを使用)。

SIGKILLはトラップできないkillシグナルです。

編集 3回目、これは正しいと思います。すべてをドキュメントと照合しました。わかります。

1
Charles Stewart

他の答えがありそうなシナリオのようですが、子を正しく処理しないスクリプトを実行している可能性もあります。私は最近、同様のシナリオに遭遇しました。スクリプトを強制終了しても、そのスクリプトの子プロセスは強制終了されません。

一般に、このような状況になった場合は、実行しているすべてのプロセスを確認する必要があります。 psのマンページを確認する必要があります。 (man ps)プロセス間の親子関係を示すps auxwfを使用するのが特に好きです。 pstreeも同様のことをします。これを別のターミナルから実行する必要がありますbeforeプロセスを強制終了して、通常の状況でどのように見えるかを確認し、子プロセスを識別します。

次に、そのメインプロセスを(^ Cで)強制終了する場合は、psの出力を再度チェックして、何かが変更されていないかどうかを確認します。子プロセスがまだ存在する場合は、killコマンドを使用してそれらを強制終了できます。 (man killを参照)

0
TREE

多くのプロセスは、割り込み信号をキャッチするために割り込みハンドラーをインストールできますが、デフォルトでは中断しないプロセスです。

プロセスを強制的に終了するには、SIGQUIT(Ctrl- \)を送信します。

0
njd