linux - 将命令结果分配给变量时 Shell 挂起

标签 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 进程并运行。 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

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

最佳答案

这可能是你在 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详细解释了后台进程和文件描述符之间的关系。基本上:

Background (better: forked) processes inherit the file descriptors, and Running a command in backticks means to collect its stdout until its stdout is closed

关于linux - 将命令结果分配给变量时 Shell 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16493302/

相关文章:

linux - Fedora Core 中 rc.local 中错误的 insmod 如何拯救 Linux 系统?

linux - Bash 脚本从第二个 bash 脚本获取变量

linux - 将并发客户端桥接到单个连接的代理

bash - 通过管道从标准输出中剪切和排序分隔日期

git - 由于解析器错误,将更复杂的脚本添加为 Git 别名不起作用

bash - 为什么带有后缀的基本名称与 find 一起使用时在子 shell 中不起作用?

bash - 外壳 sha1($salt.$password) 错误

linux - Debian 8 单用户模式下强制登录密码提示

macos - 计算机重新启动时启动的任务卸载

linux - 将 ls 命令的输出存储在 shell 变量中