为什么 $$ 返回与父进程相同的 id



我对 Bash 有问题,我不知道为什么.
在外壳下,我输入:

echo $$    ## print 2433
(echo $$)  ## also print 2433
(./getpid) ## print 2602

其中getpid是一个获取当前 pid 的 C 程序,例如:

   int main() {
    printf("%d", (int)getpid());
    return 0;
   }

让我感到困惑的是:

    我认为
  1. "(命令)"是一个子进程(我说得对吗?),我认为它的 pid 应该与其父 pid 不同,但它们是相同的,为什么......
  2. 当我使用我的程序在括号之间显示 pid 时,它显示的 pid 是不同的,对吗?
  3. $$像宏一样吗?

你可以帮我吗?

$$定义为

在子shell中返回父级的进程ID;从手册页的"特殊参数"下:

$ 扩展到外壳的进程 ID。 在 () 子外壳中,它扩展到当前外壳的进程 ID,而不是子外壳。

在第 4 bash中,可以使用 BASHPID 获取子进程 ID。

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

您可以使用以下方法之一。

  • $!是最后一个后台进程的 PID。
  • kill -0 $PID检查它是否仍在运行。
  • $$是当前外壳的 PID。
  1. 括号在 Bash 中调用子壳。由于它只是一个子外壳,它可能具有相同的 PID - 取决于实现。
  2. 你调用的C程序是一个单独的进程,它有自己独特的PID - 不管它是否在子壳中。
  3. $$ 是当前脚本 PID 的 Bash 中的别名。在此处查看$$$BASHPID之间的差异,以及包含嵌套级别的附加变量$BASH_SUBSHELL的正上方。

如果你想让你的C程序打印shell的PID,试着getppid()

这是获得正确 pid 的一种通用方法

pid=$(cut -d' ' -f4 < /proc/self/stat)

同样的好为子工作

SUB(){
    pid=$(cut -d' ' -f4 < /proc/self/stat)
    echo "$$ != $pid"
}
echo "pid = $$"
(SUB)

检查输出

pid = 8099
8099 != 8100

如果你问如何获取已知命令的PID,它将类似于这样:

如果您发出了以下命令 发出的 #The 命令是***

dd if=/dev/diskx of=/dev/disky


然后,您将使用:

PIDs=$(ps | grep dd | grep if | cut -b 1-5)

这里发生的事情是它将所有需要的唯一字符管道到一个字段,并且可以使用该字段进行回显

回声$PIDs

如果你想要一个简单的shell脚本来获取变量的最大PID,请这样做

pid=$(cat /proc/sys/kernel/pid_max)
echo $pid

这将打印出最大PID可以。

实现此目的的便携式方法

get_own_pid() {
  # This function being called in a subshell,
  # it must returns the pid of the parent of the "cut" command parent
  cut -d' ' -f4 < /proc/self/stat 
    | xargs -I% sh -c 'cut -d" " -f4 < /proc/%/stat'
}
get_parent_pid() {
  # Same thing but repeating the last command once more to get the parent one level above
  cut -d' ' -f4 < /proc/self/stat 
    | xargs -I% sh -c 'cut -d" " -f4 < /proc/%/stat' 
    | xargs -I% sh -c 'cut -d" " -f4 < /proc/%/stat'
}

# Here pid is the same as the $$ pid because called from main process
MY_PID=$(get_own_pid)
echo "$$ == ${MY_PID}"
# Here called in a subprocess, the returned pid is different
(
  MY_CHILD_PID=$(get_own_pid)
  PARENT_PID_FROM_CHILD=$(get_parent_pid)
  echo "$$ != ${MY_CHILD_PID}"
  echo "$$ == ${PARENT_PID_FROM_CHILD}"
)

灵感来自阿尔乔姆·拉普金的回答,谢谢!

相关内容

  • 没有找到相关文章

最新更新