我正在尝试获取当前正在执行子外壳的pid -但$$仅返回父pid:
#!/usr/bin/sh
x() {
echo "I am a subshell x echo 1 and my pid is $$"
}
y() {
echo "I am a subshell y echo 1 and my pid is $$"
}
echo "I am the parent shell and my pid is $$"
x &
echo "Just launched x and the pid is $! "
y &
echo "Just launched y and the pid is $! "
wait输出
I am the parent shell and my pid is 3107
Just launched x and the pid is 3108
I am a subshell x echo 1 and my pid is 3107
Just launched y and the pid is 3109
I am a subshell y echo 1 and my pid is 3107正如您在上面看到的,当我从我的后台函数运行$$时,它不会像我从父shell运行$!时那样显示PID。
发布于 2013-12-22 11:45:25
现代狂欢
如果您运行的是bash v4或更好的版本,那么可以在$BASHPID中找到该子subshell的PID。例如:
$ echo $$ $BASHPID ; ( echo $$ $BASHPID )
32326 32326
32326 1519在主shell中,$BASHPID与$$相同。在subshell中,它被更新为subshell的PID。
旧bash ( 3.x或更早版本)
在版本4之前,您需要一个workaround
$ echo $$; ( : ; bash -c 'echo $PPID' )
11364
30279(帽子提示: kubanczyk)
为什么是冒号?
请注意,在没有冒号的情况下,解决方法是不能使用:
$ echo $$; ( bash -c 'echo $PPID' )
11364
11364在上面的代码中,似乎从来没有创建子shell,因此第二个语句返回主shell的PID。相反,如果我们在括号中放入两个语句,则会创建子subshell,并且输出如我们所预期的那样。即使另一条语句只是一个冒号,:也是如此。在shell中,:是一个无操作:它什么也不做。然而,在我们的例子中,它确实强制创建子subshell,这足以完成我们想要的。
破折号
在类似debian的系统上,dash是默认的shell (/bin/sh)。PPID方法适用于dash,但还有另一个问题:
$ echo $$; ( dash -c 'echo $PPID' )
5791
5791
$ echo $$; ( : ; dash -c 'echo $PPID' )
5791
5791
$ echo $$; ( dash -c 'echo $PPID'; : )
5791
20961对于dash,将:命令放在命令之前是不够的,而将它放在命令之后是不够的。
POSIX
POSIX specification中包含PPID。
可移植性
mklement0报告以下命令与bash、dash、和 zsh 的工作方式相同,但不适用于 ksh
echo $$; (sh -c 'echo $PPID' && :)发布于 2013-12-22 11:31:08
输出是正确的。
这里来自bash的手册页。
特殊参数
shell对几个参数进行了特殊处理。这些参数只能引用,不允许赋值。
*扩展到位置参数,从1开始。当扩展发生在双引号内时,它将扩展为一个单词,每个参数的值由IFS特殊变量的第一个字符分隔。也就是说,"$*"等同于"$1c$2c...",其中c是IFS值的第一个字符。如果未设置IFS,则参数之间用空格分隔。如果IFS为null,则在没有中间分隔符的情况下连接参数。
@扩展到位置参数,从1开始。当扩展出现在双引号内时,每个参数都扩展为一个单独的单词。也就是说,如果双引号扩展出现在单词内,则"$@"等效于"$1" "$2" ...,第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。当没有位置参数时,"$@"和$@展开为空(即,它们被删除)。
#扩展为以十进制表示的位置参数数量。
?扩展到最近执行的前台管道的退出状态。
在调用时,通过设置内置命令或由-本身设置的那些选项(如-i选项),shell将扩展到当前的选项标志。
$展开为shell的进程ID。在()子shell中,它扩展为当前shell的进程ID,而不是子shell。
!扩展为最近执行的后台(异步)命令的进程ID。
要获得子subshell中的PID,可以使用BASHPID。这是一个仅限bash的环境变量。
您的新脚本将如下所示。
#!/bin/bash
x() {
echo "I am a subshell x echo 1 and my pid is $BASHPID"
}
y() {
eval echo "I am a subshell y echo 1 and my pid is $BASHPID"
}
echo "I am the parent shell and my pid is $$"
x &
echo "Just launched x and the pid is $! "
y &
echo "Just launched y and the pid is $! "
wait发布于 2018-09-25 20:39:47
如果您使用Linux-kernel,您可以使用Linux-kernel的/proc/self特性来完成此操作:
最简单的形式:cd -P /proc/self && basename "${PWD}"
保留PWD和OLDPWD变量:PWD_BACKUP="${PWD}";OLDPWD_BACKUP="${OLDPWD}";cd -P /proc/self && basename "${PWD}";cd "${PWD_BACKUP}";OLDPWD="${OLDPWD_BACKUP}"
例如:
$ cd -P /proc/self && basename "${PWD}"
26758
$ (cd -P /proc/self && basename "${PWD}")
26959
$ (cd -P /proc/self && basename "${PWD}")
26961
$ https://stackoverflow.com/questions/20725925
复制相似问题