web-dev-qa-db-ja.com

bashのようにプロセスを一時停止および再開する方法

この質問は次のフォローアップです: プロセスを一時停止および再開する方法

私はgnome-terminalのbashセッションからFirefoxを起動しました。

プロセスツリーは次のようになります。

$ ps -e -o pid,ppid,cmd -H
 1828     1   gnome-terminal
26677  1828     bash
27980 26677       /bin/sh /usr/lib/firefox-3.6.15/firefox
27985 27980         /bin/sh /usr/lib/firefox-3.6.15/run-mozilla.sh /usr/lib/firefox-3.6.15/firefox-bin
27989 27985           /usr/lib/firefox-3.6.15/firefox-bin
28012 27989             /usr/lib/firefox-3.6.15/plugin-container /usr/lib/Adobe-flashplugin/libflashplayer.so 27989 plugin true

BashでCTRL+Zを押すと、Firefoxが一時停止します。コマンドbg(またはfg)を発行すると、Firefoxが再開されます。これは予想通りです。

別の端末でkill -s SIGTSTP 27980コマンドを発行すると、最初の端末に[1]+ Stopped firefoxという行が出力されます(CTRL+Zを押したときと同じように)が、Firefoxを一時停止しません。シェルスクリプトのみを一時停止するものと想定しています。

別の端末でkill -s SIGTSTP 27989(PIDに注意)というコマンドを発行すると、Firefoxが一時停止します。最初の端末はこれに注意しません。

Bashはプロセスツリー全体をどのように中断しますか?それは単にツリーを横断し、すべての子をSIGTSTPしますか?

13
lesmana

シェルジョブは「プロセスグループ」にあります。拡張PGRP出力のps列を見てください。これらは、ジョブ制御と、誰が端末(実またはpty)を「所有」しているかを判別するために使用されます。

プロセスグループはグループ内の最初のプロセス(「プロセスグループリーダー」)によって識別されるため、POSIX(System Vから取得)は負のプロセスIDを使用してプロセスグループを示します。したがって、psを使用してプロセスグループを決定し、次にkill -s TSTP "-$pgrp"を使用します。 (ps -u"$USER" -opid,ppid,pgrp,cmdを試してください。)

プロセスツリーでは、プロセスグループはfirefoxによって起動されたbashスクリプトで始まるため、プロセスグループは27980で、コマンドはkill -s TSTP -27980になります。

当然、プロセスグループを再開するには、kill -s CONT -- -27980を発行します。

17
geekosaur