Bashスクリプトのバックグラウンドでコマンドを使用すると、Bash親プロセスが子プロセスの前に終了するのはなぜですか?

Bashスクリプトのバックグラウンドでコマンドを使用すると、Bash親プロセスが子プロセスの前に終了するのはなぜですか?

次の単純な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子が完了するのを待って一時停止します。スクリプトを親スクリプトとして扱います。後者の場合、親は停止/睡眠状態で表示されます。

おすすめ記事