3

我是shell新手,我刚刚了解到使用(命令)会创建一个新的子shell并执行命令,所以我尝试打印父shell和子shell的pid:

#!/bin/bash

echo $$
echo "`echo $$`"
sleep 4
var=$(echo $$;sleep 4)
echo $var

但答案是:

$./test.sh
9098
9098
9098

我的问题是:

  1. 为什么只有三个回声打印?我的代码中有 4 个回声。
  2. 为什么三个pid是一样的?subshel​​l 的pid 显然和他父亲的不一样。

非常感谢您的回答:)

4

3 回答 3

6

首先,分配捕获孩子的标准输出并将其放入var,而不是打印它:

var=$(echo $$;sleep 4)

这可以通过以下方式看到:

$ xyzzy=$(echo hello)
$ echo $xyzzy
hello

其次,所有这些$$变量都在当前shell 中进行评估,这意味着它们在任何子进程启动之前都已转换为当前 PID。孩子们看到已经生成的PID。换句话说,孩子们正在执行echo 9098而不是echo $$

如果你想要孩子的PID,你必须防止在父母中翻译,例如使用单引号:

bash -c 'echo $$'
于 2012-04-05T06:40:30.180 回答
0
echo "one.sh $$"
echo `eval echo '$$'`

我期待上面打印不同的pid,但事实并非如此。它正在创建一个子进程。通过在``中添加 sleep 来验证。

echo "one.sh $$"
echo `eval "echo '$$'";sleep 10`

从脚本执行上述内容并运行ps会显示两个进程 one.sh(脚本的名称)和睡眠。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
test    12685  0.0  0.0   8720  1012 pts/15   S+   13:50   0:00      \_ bash one.sh
test    12686  0.0  0.0   8720   604 pts/15   S+   13:50   0:00          \_ bash one.sh
test    12687  0.0  0.0   3804   452 pts/15   S+   13:50   0:00              \_ sleep 10

这是产生的输出

one.sh 12685
12685

不知道我错过了什么。

于 2012-04-05T08:25:40.550 回答
-1

解决办法是$!。如:

#!/bin/bash

echo "parent" $$
yes > /dev/null &
echo "child" $!

输出:

$ ./prueba.sh
parent 30207
child 30209
于 2012-05-30T13:12:35.470 回答