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

Ron*_*Ron 5 bash process background-process

我在 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
Run Code Online (Sandbox Code Playgroud)

执行时:

    /tmp$ ./test
    I am 5253
    Started: 5254
    Started: 5256
    Started: 5258
    /tmp$ aa :: 5253
    bb :: 5253
    cc :: 5253
Run Code Online (Sandbox Code Playgroud)

所以 - 父脚本 (/tmp/test) 作为 PID 5253 执行并用 PID 5254、5256 和 5258 触发三个后台进程。但是这些后台进程中的每一个都使用 $$ 获得值 5253。

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

小智 9

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

BASHPID

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

$$

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

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


Sté*_*las 6

bash

echo "$BASHPID"
Run Code Online (Sandbox Code Playgroud)

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

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

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

$ readlink -f /proc/self "/proc/$BASHPID"
/proc/30868
/proc/30747
$ (readlink -f /proc/self "/proc/$BASHPID")
/proc/30869
/proc/30869
Run Code Online (Sandbox Code Playgroud)

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

zsh当量是在zsh/system模块:

$ zmodload zsh/system
$ echo $$ $sysparams[pid]
5155 5155
$ (echo $$ $sysparams[pid])
5155 30979
Run Code Online (Sandbox Code Playgroud)

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

便携,你可以这样做:

pid=$(sh -c 'echo "$PPID"')
Run Code Online (Sandbox Code Playgroud)

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