将命令结果分配给变量时,Shell会挂起

时间:2013-05-11 02:54:13

标签: linux shell command-substitution

我最初的问题是杀死一个进程&超时的孩子。我发现GNU timeout是一个不错的选择。

然而,在这个测试用例中,事情变得奇怪了:

假设我们有test1.sh这样:

#!/bin/sh
# test1.sh
output=`timeout 2 ./run.sh`
echo $output

run.sh是这样的:

#!/bin/sh
# run.sh
sleep 8s&

直观地说,我们应该立即退出test1.sh,因为init将负责那个愚蠢的sleep流程,然后会run.sh退出。

然而:

sh-4.2$ time ./test1.sh

real    0m8.022s
user    0m0.013s
sys     0m0.003s

如果我创建此test2.sh

#!/bin/sh
# test2.sh
timeout 2 ./run.sh
sh-4.2$ time ./test2.sh

real    0m0.014s
user    0m0.003s
sys     0m0.007s

所以,显然我们在命令替换期间遇到了什么问题,但为什么呢?

1 个答案:

答案 0 :(得分:3)

这可能是你在shell脚本中的方式 -

`timeout 2 ./run.sh` 

- 你正在使用命令替换,所以只要命令没有完成执行,就无法进行替换,因为输出不存在......这可以解释你看到的输出。

试试这个看到类似的结果......

echo "hello `sleep 2 &`"

另一个感兴趣的剧本 -

$ cat y.sh
echo "hi"
sleep 2 &
echo "bye"
sleep 2 &

使用

运行
echo "hello `sh y.sh`"

$time sh y.sh
hi
bye

real    0m0.006s
user    0m0.000s
sys     0m0.004s

$time echo "hello `sh y.sh`"
hello hi
bye

real    0m2.008s
user    0m0.004s
sys     0m0.000s

This page详细介绍了后台进程和文件描述符之间的关系。 Basicly:

  

后台(更好:分叉)进程继承文件描述符,   并且在反引号中运行命令意味着收集它的标准输出直到   它的标准已关闭