第二个过程来自哪里

时间:2017-05-02 13:30:20

标签: bash shell sh

将以下代码放入shell脚本中,例如x.sh和chmod + x x.sh

  

./ x.sh

我的期望是只有一行,而实际上,我有两行:

tmp $ ./x.sh
52140 ttys003    0:00.00 /bin/sh ./x.sh
52142 ttys003    0:00.00 /bin/sh ./x.sh

我的问题是52142来自哪里?

#!/bin/sh
myself=$(basename $0)
running=$(ps -A | grep "$myself" |grep -v grep)
echo "${running}"

注意:这是在MacOS 10.12上

使用新实验更新了问题:

#!/bin/sh
myself=$(basename $0)
running=$(ps -fe | grep $myself |grep -v grep)

echo ==== '$(ps -fe | grep "$myself" |grep -v grep)' ====
echo "${running}"
echo 

running=$(ps -fe | cat)
echo ==== '$(ps -fe | cat) |grep $myself' ====
echo "${running}"|grep $myself
echo 

running=$(ps -fe)
echo ==== '$(ps -fe) |grep $myself' ====
echo "${running}" |grep $myself

MacOS 10.12上的输出是:

==== $(ps -fe | grep "$myself" |grep -v grep) ====
  501 59912 81738   0  9:01AM ttys003    0:00.00 /bin/sh ./x.sh
  501 59914 59912   0  9:01AM ttys003    0:00.00 /bin/sh ./x.sh

==== $(ps -fe | cat) |grep $myself ====
  501 59912 81738   0  9:01AM ttys003    0:00.00 /bin/sh ./x.sh
  501 59918 59912   0  9:01AM ttys003    0:00.00 /bin/sh ./x.sh

==== $(ps -fe) |grep $myself ====
  501 59912 81738   0  9:01AM ttys003    0:00.00 /bin/sh ./x.sh

从上面看,子shell似乎也与管道有关。

1 个答案:

答案 0 :(得分:4)

$(command)是命令替换。 command已在子shell中执行。

子shell是原始shell(或shell脚本)的子进程(fork),如果使用ps进行检查,则文件名部分与原始(父)shell脚本相同。

您可以将x.sh更改为:

进行验证
echo "$(ps -fe --forest>foo.txt)"

使用--forest ps将输出具有子进程的树结构。打开foo.txt搜索x.sh,您将看到树状结构。

如果我在我的机器上跑,我得到:

kent     20866   707  0 15:55     \_ urxvt 
kent     20867 20866  0 15:55         \_ zsh
kent     21457 20867  0 15:56             \_ sh ./x.sh
kent     21459 21457  0 15:56                 \_ sh ./x.sh #subshell
kent     21460 21459  0 15:56                     \_ ps -fe --forest

如果我们再添加一个图层,请将脚本更改为:

(
echo "$(ps -fe --forest>foo.txt)"
)

现在我们的x.sh将创建两个嵌套的子shell,如果我运行并检查我的foo.txt

... 25882 27657  0 16:05 ...  \_ -zsh
... 31027 25882  0 16:16 ...      \_ sh ./x.sh
... 31028 31027  0 16:16 ...          \_ sh ./x.sh #subshell1
... 31029 31028  0 16:16 ...              \_ sh ./x.sh #subshell2
... 31031 31029  0 16:16 ...                  \_ ps -fe --forest

$PPID也显示出来。