从 shell 脚本中的后台函数中获取 PID

Get PID from within backgrounded function in shell script

这看起来像是 的副本,但事实并非如此。接受的答案是脚本父进程 ID。

以下脚本:

#!/bin/bash

function foo {
  # I want to know my PID
  echo foo PID=$$
  echo foo PPID=$PPID
  sleep 1
}

echo Script PID=$$
echo Script PPID=$PPID
foo &
echo job PID=$!
ps -fH
wait

产生以下输出:

Script PID=3694
Script PPID=27899
job PID=3695
foo PID=3694
foo PPID=27899
UID        PID  PPID  C STIME TTY          TIME CMD
fred     27899  6622  0 11:03 pts/10   00:00:00 /bin/bash
fred      3694 27899  0 15:10 pts/10   00:00:00   /bin/bash /tmp/test
fred      3695  3694  0 15:10 pts/10   00:00:00     /bin/bash /tmp/test
fred      3697  3695  0 15:10 pts/10   00:00:00       sleep 1
fred      3696  3694 99 15:10 pts/10   00:00:00     ps -fH

由于 foo() 在后台 运行,我希望在 foo 中 $$ 计算其 PID (3695),但它不会计算调用脚本 PID (3694)。

在 foo 函数中,如何获取它自己的 PID?

更新:已根据要求将 ps -fp $! 更改为 ps -fH

在后台运行函数时,Bash 可能会使用子shell。 PIDPPID 变量没有改变,但是如果你回显 BASHPID 变量,你会看到它在你的函数内部发生了变化。

我认为您看到的行为是有意为之的,但与 shell.

启动的永恒程序相比,函数的行为完全不同

您可以通过将函数中的代码放在单独的脚本中并使用

调用来强制启动单独的进程
bash `other_script`

无论您使用什么shell,都应该创建一个新进程。

您将需要 export 子项中需要的任何变量,并且不能对父项可见的子项中的变量进行赋值。

我找到了一种适用于 bash 和 ksh(可能还有其他 shell)的简单方法。

$SHELL -c 'echo $PPID'

调用上述命令时,PPID 设置为恰好是函数 foo 的调用进程。