您已经获得了有关子进程的正确信息。只有在您的情况下,ps 不知道或不想为您在后台启动的链式子进程显示正确的 COMMAND 名称 - 这可能会让您感到困惑。
看起来这是链式命令的情况(.. && ...,因此它与exit 1 也可能是echo 5 等无关)其中process group leader 名称显示为cmd 名称而是。
来自 (ps man page)
`cmd | COMMAND`: simple name of executable
# Process state codes
`S`: interruptible sleep (waiting for an event to complete)
`+`: is in the foreground process group
在您的ps | grep 输出中查看S+。
因此,您可以稍微调整一下您的脚本,以确认您确实捕获(d)有关子进程的正确信息,如下所示:
cat <<"END"> z
#! /bin/bash
sleep 20 && exit 1 &
ret=$!
echo $ret
jobs -l
# display parent and child process info
# -j Jobs format
ps -j $$ $ret
END
echo $ret 的输出:
30274
jobs -l的输出:
[1]+ 30274 Running sleep 20 && exit 1 &
ps -j $$ $ret的输出:
PID PGID SID TTY STAT TIME COMMAND
30273 30273 21804 pts/0 S+ 0:00 /bin/bash ./z
30274 30273 21804 pts/0 S+ 0:00 /bin/bash ./z
注意,父子进程的PGID相同,而jobs -l和ps ...显示的子进程的pid 30274匹配。
此外,如果您将sleep 20 && exit 1 & 更改为bash -c 'sleep 20 && exit 1' &,这次您将获得正确的子命令名称,如下所示(参见上面的输出顺序):
30384
[1]+ 30384 Running bash -c 'sleep 20 && exit 1' &
PID PGID SID TTY STAT TIME COMMAND
30383 30383 21804 pts/0 S+ 0:00 /bin/bash ./z
30384 30383 21804 pts/0 S+ 0:00 bash -c sleep 20 && exit 1
最后但同样重要的是,在您的原始版本中,您也可以尝试使用 ps $ret | grep $ret 代替
pstree -s $ret
来自pstree man page
-s:显示指定进程的父进程。
这将为您提供类似于下面的输出,这也将确认您获得了sleep 20 && exit 1 & 的正确进程信息:
systemd───systemd───gnome-terminal-───bash───bash───sleep