bash发布了额外的,虚假的后台进程

Har*_*rry 1 linux bash jobs background

我看到一个非常非常奇怪的行为与bash(RHEL 5.3版本3.2.25).

我有一个'Launcher'脚本执行以下操作(作为前台进程,在一个始终保持打开的终端中运行):

  1. 它在后台启动一个程序A,然后退出.
  2. 然后,A在后台启动程序B的两个(进程)实例(例如:B1,B2);
  3. A,还在后台启动程序C的一个实例.

上面的想法主要是让A,C和两个B彼此通信,直到它们被用户杀死.(它们继续while sleep DURATION; do ... ; done循环运行.)

问题:

完成上述3个步骤之后,当我ps -ef从另一个终端窗口重复发出时,我有时会看到一些额外的,虚假的B实例(比如说B3,B4 ......)和/或有时会列出一个额外的,虚假的A实例!

这些额外的实例是暂时的 - 它们来自ps -ef列表.

此外,这些虚假实例恰好是有效(或期望)过程的子项 - 而不是兄弟姐妹.例如,B3和B4将分别列出B1和B2作为其父级; 同样,假的A2会将A列为其父级!

现在,我PRETTY非常确信我是NO WAY从B内部产生的任何追加B的情况下,也没有任何一个实例从里面A.

那么,这里发生了什么?

提前谢谢了.

PS:我已经看到了一个类似的问题(多个虚假实例),一段时间回到cron作业的背景下,这些作业被设计成在初次首次发布时无限期地挂起.在这里,我会看到我的cron作业的多个实例,即使我有明确的逻辑来防止crond启动任何其他实例(通过检查磁盘上是否存在锁定文件).而且,即使在这里,我也无法弄清楚问题.


$ ps -ejfH 
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     16143 28525 28474 11126  0 23:14 pts/1    00:00:00       [B] <defunct>
root     16144 28525 28474 11126  0 23:14 pts/1    00:00:00       /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH 
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root     18579 28503 28474 11126  0 23:14 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     22717 28525 28474 11126  0 23:14 pts/1    00:00:00       /bin/bash B 
root     22718 22717 28474 11126  0 23:14 pts/1    00:00:00         /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:31   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:26     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:23     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     32021 28531 28474 11126  0 23:15 pts/1    00:00:00       /bin/bash B 
root     32023 32021 28474 11126  0 23:15 pts/1    00:00:00         [B] <defunct>
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root     32013 28503 28474 11126  0 23:15 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:01     /bin/bash C
root      2310 28503 28474 11126  0 23:15 pts/1    00:00:00     /bin/bash A
root      2324  2310 28474 11126  0 23:15 pts/1    00:00:00       /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root      9219 28531 28474 11126  0 23:16 pts/1    00:00:00       [B] <defunct>
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:32   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C
root      9692 28503 28474 11126  0 23:16 pts/1    00:00:00     /bin/bash A

$ ps -ejfH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root     28503     1 28474 11126  0 22:14 pts/1    00:00:33   /bin/bash A
root     28525 28503 28474 11126  0 22:14 pts/1    00:00:27     /bin/bash B 
root     28531 28503 28474 11126  0 22:14 pts/1    00:00:24     /bin/bash B 
root     28566 28503 28474 11126  0 22:14 pts/1    00:00:02     /bin/bash C
root     15686 28503 28474 11126  0 23:16 pts/1    00:00:00     /bin/bash A
Run Code Online (Sandbox Code Playgroud)

Gor*_*son 5

有许多bash功能可以生成子shell来执行脚本的一部分.我的猜测是你的A和B脚本正在使用其中的一些功能.除了通过封装命令显式创建子shell之外( ... ),还将为管道中运行的任何bash命令,命令替换($( ... )或反引号)或后台运行创建子shell &.这是一个说明这些的脚本:

$ cat a
#!/bin/bash

echo "Initial subshell count: $BASH_SUBSHELL"
ps -opid,ppid,command | egrep "PID|bash ./a"

echo "input" | while read line; do
    echo "Subshell count in pipeline: $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
done

output=$(echo "Subshell count in \$(): $BASH_SUBSHELL"
   ps -opid,ppid,command | egrep "PID|bash ./a"
)
echo "$output"

(   echo "Subshell count in (): $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
)

{   echo "Subshell count in backgrounded command: $BASH_SUBSHELL"
    ps -opid,ppid,command | egrep "PID|bash ./a"
} &
sleep 1
$ ./a
Initial subshell count: 0
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1412  1410 egrep PID|bash ./a
Subshell count in pipeline: 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1414  1410 /bin/bash ./a
 1416  1414 egrep PID|bash ./a
Subshell count in $(): 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1417  1410 /bin/bash ./a
 1419  1417 egrep PID|bash ./a
Subshell count in (): 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1420  1410 /bin/bash ./a
 1422  1420 egrep PID|bash ./a
Subshell count in backgrounded command: 1
  PID  PPID COMMAND
 1410   158 /bin/bash ./a
 1423  1410 /bin/bash ./a
 1426  1423 egrep PID|bash ./a
Run Code Online (Sandbox Code Playgroud)

(注意:在echo ... | while ...示例中,echowhile和while循环都在子shell中执行;但echo命令退出的速度太快,ps无法显示它.)