2017-06-26 35 views
3

我有一个shell脚本,命名为test.sh:有巴什 - 一个脚本两个进程

start 
1 
2 
end 

所以我的问题是,为什么两个测试:

#!/bin/bash 
echo "start" 
ps xc | grep test.sh | grep -v grep | wc -l 
vartest=`ps xc | grep test.sh | grep -v grep | wc -l ` 
echo $vartest 
echo "end" 

输出结果是当我使用``调用ps时,.sh进程正在运行(同样发生在$()),而不是直接调用ps时? 我如何得到想要的结果(1)?

+0

可在4.3.11上重现;不知道是什么造成这一点。 – Blacksilver

+0

因为你的以'ps..'开头的行本身可能出现在秒ps的调用中,所以我猜 – derHugo

+0

@derHugo:不行。如果我在ps之前将10倍ps和10倍之后,这条线仍然输出1 – user6050469

回答

6

当你启动一个子shell时,和反引号一样,bash自行分叉,然后执行你想运行的命令。然后,你还运行一个管道,使所有这些管道都在自己的子壳体中运行,所以你最终得到了等待管道完成的脚本的“额外”副本,以便收集输出并将其返回给原始剧本。

我们将使用(...)到子shell中显式运行的流程和使用pgrep命令,它确实ps | grep "name" | grep -v grep对我们来说,只是向我们展示符合我们的字符串的过程做一个小小的expermiment:

echo "Start" 
(pgrep test.sh) 
(pgrep test.sh) | wc -l 
(pgrep test.sh | wc -l) 
echo "end" 

其上运行我产生输出:

Start 
30885 
1 
2 
end 

因此,我们可以看到,在一个子shell中运行pgrep test.sh只能找到test.sh的单个实例,即使子shell是意料之中t管道本身。但是,如果子shell包含管道,那么我们将获得脚本的分叉副本,以等待管道完成

+0

你可以添加一个注释来解释'pgrep test.sh'的作用,以及括号'(foo)'的作用? – Blacksilver

+0

@Blacksilver'ps' +'grep' ='pgrep' – ceving

+0

我试着创建一个只有testvar ='sleep 20'的文件。我运行脚本,并在脚本运行(睡眠)的同时,使用ps检查进程。在这种情况下只有一个test.sh文件。所以使用反引号并不总是意味着新的过程。是否有另一个条件有一个子过程? (比如,是因为我使用了管道吗?)。谢谢 ! – user6050469