上記のコマンドの説明

上記のコマンドの説明

子プロセスにいるときに一部の信号またはPIDによるシャットダウンを介して親プロセスを終了する正しいbashコマンド/ガイドラインは何ですか?

ベストアンサー1

私が正しく理解したら、考えられる解決策の1つはtrapシェルプロセスまたはコマンドを使用することです。

ソリューション1

メモ:それを使用するtrapことは、シェルを使用するときにのみ動作するようです。たとえば、端末でコマンドを実行したり、スクリプト(たとえばmyscript.shtrap

例を見てみましょう。

ps -fH現在の親プロセス(シェル)に入ると、zsh次のようになります。

%> ps -fH
#Output:
UID        PID  PPID  C STIME TTY          TIME CMD
edgar    17932 24608  0 23:37 pts/2    00:00:00 /bin/zsh
edgar    18001 17932  0 23:38 pts/2    00:00:00   ps -fH

それでは、子プロセスを実行しbashps -H再入力します。

%> bash
(bash shell) %> ps -fH
#Output:
UID        PID  PPID  C STIME TTY          TIME CMD
edgar    17932 24608  0 23:37 pts/2    00:00:00 /bin/zsh
edgar    18012 17932  0 23:38 pts/2    00:00:00   bash
edgar    18030 18012  0 23:38 pts/2    00:00:00     ps -fH

ご覧のとおり、bashシェルの親プロセスにはzshPIDがあります17932

特定のプロセスのPPIDを取得するには、を使用する必要があります。たとえば、現在のプロセスの親プロセスIDをps -o ppid= $SOME_PID取得するには、以下を使用する必要があります。bash

(bash shell) %> ps -o ppid= 18012
#Output:
17932

それとも、お勧めできる他のものがありますか?

(bash shell) %> ps -o ppid= $$
#Output
17932

$$現在実行中のプロセスのプロセスIDを取得しています。この場合はbash

最後に、親プロセス(この場合)を終了するには、zsh次のコマンドを実行する必要があります。

(bash shell) %> trap "echo Killing parent process $(ps -o ppid= $$); kill -9 $(ps -o ppid= $$)" 0 
#Or
(bash shell) %> trap "kill -9 $(ps -o ppid= $$)" 0

入力exitまたは押すと、Ctrl + D親プロセスzshも終了します。

(bash shell) %> exit
#zsh was killed too, so the terminal will show the following output:
Warning: Program '/bin/zsh' crashed

避けるためにzshがクラッシュしましたbashシェルを2回実行できるというメッセージ

ソリューション2

このstraceコマンドを使用すると、すべてのプロセスで機能します。
例を見てみましょう。

バックグラウンドでプロセスを実行し、straceそのプロセスを終了できる親プロセスに接続します。
まず、シェルでbash実行します。zsh

(zsh shell) %> bash

それでは、bashシェルでバックグラウンドでプロセスを実行しましょう。この例では、このsleepコマンドを使用して対応するPPID(親プロセスID)を取得します。

(bash shell) %> sleep 60& #sleep 1 minute (in background)
processID=$! #with $! we get the pid of the last executed process, in this case the sleep command
parentID=$(ps -o ppid= $processID) 

ps -fH出力を見ると、次のような結果が得られます。

UID        PID  PPID  C STIME TTY          TIME CMD
edgar    21593 21579  0 00:43 pts/1    00:00:00 /bin/zsh
edgar    22971 21593  0 01:03 pts/1    00:00:00   bash
edgar    23011 22971  0 01:07 pts/1    00:00:00     sleep 60
edgar    23012 22971  0 01:08 pts/1    00:00:00     ps -fH

bashこれで完了したら、親プロセスを終了しようとしますsleep 60。これを行うには、次のコマンドを使用しますstrace -p

strace -p $processID ; kill -9 $parentID

strace -p は、PID を使用してプロセスをリンクするために使用されます。

プロセス$processID(sleepコマンド)が完了すると、killコマンドが実行され、$ parentID(bashシェル)が終了します。

メモ:straceシグナルを受け取ったときにコマンドを実行できるかどうかはわかりません。この方法は、プロセスが完了した後にのみ機能します。

上記のコマンドの説明

psの使用

によるとps --help

-f - フルリスト
--forest-H - プロセス階層を表示する

ps -f出力には、単に使用するよりも多くの列が表示されますps。私はすべてのプロセスをps -f理解したPPID

ヘルプに示されているようにps -H(を使用することもできます)を使用すると、プロセス階層が表示されます。つまり、特定のプロセスの各サブプロセスが特別な形式で表示されます。ps --forest実行すると、ps -H次のような結果が得られます。

PID TTY          TIME CMD
 2872 pts/1    00:00:00 zsh
 3771 pts/1    00:00:00   bash
 7259 pts/1    00:00:00     ps

psこれがの子プロセスでありbash、これがのプロセスであることがわかりますzsh

代わりに、以下を実行することもできますps f(BSD構文)ps -H

%> ps f
#Output:
PID TTY      STAT   TIME COMMAND
 2872 pts/1    Ss     0:00 /bin/zsh
 3771 pts/1    S      0:00  \_ bash
 7495 pts/1    R+     0:00      \_ ps f

トラップの使用

の構文はtrap次のとおりですtrap 'commands' SIGNAL。これは、プロセスが特定のメッセージを受信するとSIGNAL実行されることを意味します。より良い説明のために、次のようにcommands入力できます。man trap

条件は、デフォルト定義ボリュームで定義されている<signal.h>ヘッダーのシグナル名テーブルにリストされているように、EXIT、0(EXITと同じ)、またはシンボル名(SIGプレフィックスなし)を使用して指定されたシグナルです。 POSIX.1-2017。
...
XSI互換システムでは、次の信号名に対応する条件でデジタル信号番号を使用することもできます。
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM

trap 'commands' 0したがって、シェルを使用している場合、'commands'シェルを終了するとトラップで指定された内容が実行されます。

たとえば、bash シェルは次のコードを受け取るechoと実行されます。SIGINT

(bash_shell) %> echo Bash PID: $$
#Output:
Bash PID: 8529
(bash_shell) %> trap 'echo Bash got SIGINT signal' 2
(bash_shell) %> kill -SIGINT 8529
#Output:
^CBash got SIGINT signal

bashシェルでkill -SIGINT 8529次を押すこともできます。Ctrl+C

メモ:一部の信号では機能しない可能性がありますtrap(SIGKILLを使用してテストしましたが機能しません)。

殺して使う

man killまたはを使用すると、man 1p killコマンドの詳細な説明を取得できます。

Kill -s シグナル名 pid

Kill -l [終了ステータス]

kill[-signal_name] pid

Kill [-signal_number] pid ...

-s signal_name
<signal.h>ヘッダーで定義されているシンボル名の1つを使用して送信する信号を指定します。 signal_name値は、SIGプレフィックスなしで大文字と小文字を区別せずに識別する必要があります。また、信号値がゼロであることを示すシンボル名0を認識する必要があります。 SIGTERMの代わりにその信号を送信する必要があります。

-signal_name
は -s signal_name と同じです。

-signal_numberは、
kill()への有効な呼び出しでSIGTERMの代わりに使用される信号を表す負でない10進数signal_numberを指定します。使用した整数値とシグネチャ値との対応関係を下表に示します。次以外の signal_number を指定する効果は未定義です。

0 0
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM

したがって、コマンドはkill -9 8990と同じですkill -SIGKILL 8990SIGKILLプロセスに転送されると、プロセスは終了/終了します。

おすすめ記事