后台进程如何知道自己的PID?

后台进程如何知道自己的PID?

我在 RH Linux 系统上使用 bash。

通常,您可以使用变量 $$ 获取自己的 PID。但是,如果脚本将其自己的函数之一作为后台进程运行 - 这是行不通的;当使用 $$ 时,所有在后台运行的函数都会获取父脚本的 PID。

例如,这是一个测试脚本:

    /tmp/test:
    #!/bin/bash
    echo "I am $$"
    function proce {
      sleep 3
      echo "$1 :: $$"
    }

    for x in aa bb cc; do
      eval "proce $x &"
      echo "Started: $!"
    done

执行时:

    /tmp$ ./test
    I am 5253
    Started: 5254
    Started: 5256
    Started: 5258
    /tmp$ aa :: 5253
    bb :: 5253
    cc :: 5253

因此,父脚本 (/tmp/test) 以 PID 5253 执行,并启动 PID 为 5254、5256 和 5258 的三个后台进程。但是这些后台进程中的每一个都通过 $$ 获取值 5253。

这些进程如何发现其实际的PID?

答案1

$BASHPID可能就是您正在寻找的。

巴什PID

扩展为当前 Bash 进程的进程 ID。这在某些情况下与 $$ 不同,例如不需要重新初始化 Bash 的子 shell。

相对于$$

($$) 扩展为 shell 的进程 ID。在 () 子 shell 中,它扩展为调用 shell 的进程 ID,而不是子 shell。

http://www.gnu.org/software/bash/manual/bashref.html#Bash-Variables

答案2

bash

echo "$BASHPID"

echo会给你评估该命令的进程的 pid

请注意(例如在 a 之后enable -n echo)它不一定与该进程的 pid 相同跑步那个echo命令。

bash(或任何 shell)用进程做自己的汤。尝试猜测哪个进程做了什么并不总是有用的。

$ readlink -f /proc/self "/proc/$BASHPID"
/proc/30868
/proc/30747
$ (readlink -f /proc/self "/proc/$BASHPID")
/proc/30869
/proc/30869

在第二种情况下,readlink在解释命令行的同一进程中执行,因为这是在该子 shell 中运行的最后一个命令(因此bash优化了 a fork())。

等效zsh项在zsh/system模块中:

$ zmodload zsh/system
$ echo $$ $sysparams[pid]
5155 5155
$ (echo $$ $sysparams[pid])
5155 30979

zsh还公开了子shell的父pid $sysparams[ppid])。

便携地,你可以这样做:

pid=$(sh -c 'echo "$PPID"')

所有 shell 都应将其sh作为解释该命令行的子 shell 的直接子级运行,因此sh应该$PPID是该子 shell。

相关内容