Bash 第二道工序从何而来
将以下代码放入shell脚本中,例如x.sh和chmod+x.sh ./x.sh 我所期望的是只有一行,而实际上,我有两行:Bash 第二道工序从何而来,bash,shell,sh,Bash,Shell,Sh,将以下代码放入shell脚本中,例如x.sh和chmod+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
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似乎也与管道相关。$(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)"
)
现在,如果我运行并检查我的foo.txt
,我们的x.sh
将创建两个嵌套的子shell:
... 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
也会显示它。管道通常通过分叉来实现。另外,$()是命令替换——听起来它可能会创建进程吗?它会生成调用本身的无限嵌套。是吗?@MaurizioBenedetti为什么?哪里?Jens,对不起,我看你有一个脚本X在无限空间中调用自己way@Jens,你应该是对的,非常感谢pst--forest
或psu$USER--forest
将使搜索更容易。非常感谢Kent。列出的子外壳似乎也与管道相关。如果$()中没有管道,则不会显示子shell。我无法在注释中附加代码,将在问题中更新。在MacOS上,不支持--forest