2

我最初的问题是在超时时杀死一个进程及其子进程。而且我发现 GNUtimeout是一个不错的选择。

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

假设我们有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

所以,很明显我们在命令替换过程中遇到了一些错误,但是为什么呢?

4

1 回答 1

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

本页详细解释了后台进程和文件描述符之间的关系。基本上:

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

于 2013-05-11T02:57:14.053 回答