将以下代码放入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似乎也与管道有关。
答案 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
也显示出来。