次の単純なbashスクリプトがあるとしましょう。
test_bg.sh
#!/bin/bash
ping www.google.ro &> /dev/null &
./test_bg.sh
実行してps -ef
後続のアクションを介して直接実行すると、プロセスping www.google.ro
がsystemd(PID 1)によって継承されることがわかります。つまり、親プロセスが完了するのを待たずに終了し、孤児プロセスを取得します。
UID PID PPID PGID SID C STIME TTY TIME CMD
root 1 0 1 1 0 Jan07 ? 00:00:21 /usr/lib/systemd/systemd --system --deserialize 21
...
...
...
nimus 461772 1 461771 458695 0 18:59 pts/1 00:00:00 ping www.google.ro
/bin/bash -c "ping www.google.ro &> /dev/null &"
もちろん。
なしでスクリプトのコードを実行すると、&
スクリプトのコードは次のようになりますtest_fg.sh
。
#!/bin/bash
ping www.google.ro &> /dev/null
次のようになりますps -efj --forest
。
UID PID PPID PGID SID C STIME TTY TIME CMD
nimus 458695 458596 458695 458695 0 17:02 pts/1 00:00:00 | \_ -bash
nimus 461907 458695 461907 458695 0 19:02 pts/1 00:00:00 | \_ /bin/bash ./test_fg.sh
nimus 461908 461907 461907 458695 0 19:02 pts/1 00:00:00 | \_ ping www.google.ro
/bin/bash ./test_fg.sh
したがって、分岐されたプロセスは、fork()とexec()の後もping www.google.ro
再び存在します。
もちろん、ping www.google.ro &> /dev/null &
メインbashプロセス(つまりセッションリーダー)で直接実行すると、次のような結果が得られます。
[nimus@localhost ~]$ ping www.google.ro &> /dev/null &
[1] 462091
[nimus@localhost ~]$ ps -efj --forest
UID PID PPID PGID SID C STIME TTY TIME CMD
root 458581 351997 458581 458581 0 17:02 ? 00:00:00 \_ sshd: nimus [priv]
nimus 458596 458581 458581 458581 0 17:02 ? 00:00:00 | \_ sshd: nimus@pts/1
nimus 458695 458596 458695 458695 0 17:02 pts/1 00:00:00 | \_ -bash
nimus 462091 458695 462091 458695 0 19:10 pts/1 00:00:00 | \_ ping www.google.ro
それでは、プロセスがping www.google.ro
スクリプトのバックグラウンドで実行されたときにプロセスが継承されるのはなぜですか?Systemd PID 1
&
ベストアンサー1
バックグラウンドでプロセスを開始すると(を使用して&
)、親プロセスと同時に実行が開始されます。スクリプトには他の操作がないため、exit
孤立プロセスが使用されますinit
。これを使用しないと、&
親はwait
子が完了するのを待って一時停止します。スクリプトを親スクリプトとして扱います。後者の場合、親は停止/睡眠状態で表示されます。