Shell脚本中的指令顺序

时间:2019-04-11 08:14:17

标签: shell background-process

我有这个简单的shell脚本:

#!/bin/sh

echo "alpha"

finish()
{
    echo "--------------------------------------------------------------"
}
trap finish EXIT

echo "bravo"

cd /non/existent/path
# cd /non/existent/path && gitk &

echo "charlie"

运行时,将按预期提供以下输出:

alpha
bravo
./test.sh: 13: cd: can't cd to /non/existent/path
charlie
--------------------------------------------------------------

但是,如果我取消注释包含gitk调用的行(即第14行),则会得到以下输出:

alpha
bravo
./test.sh: 13: cd: can't cd to /non/existent/path
charlie
--------------------------------------------------------------
./test.sh: 14: cd: can't cd to /non/existent/path

请注意,带有短划线的行不再位于末尾。知道为什么会这样吗?

我还注意到,如果我删除该行末的“&”号,则顺序将再次与我期望的一样。因此,将gitk作为后台进程启动显然会产生影响,但我不知道具体如何。

最后,是否可以修改脚本,以便我可以继续启动gitk作为后台进程,但仍在末尾显示带短划线的行?

2 个答案:

答案 0 :(得分:2)

行为符合预期,因为您通过&生成了子进程。如果您要在脚本末尾添加wait之后执行陷阱函数:

#!/bin/sh

echo "alpha"

finish()
{
    echo "--------------------------------------------------------------"
}
trap finish EXIT

echo "bravo"

cd /non/existent/path
cd /non/existent/path && gitk &

echo "charlie"
wait

这将等待所有子进程完成,然后退出(调用陷阱完成)。输出:

$ ./gautam.sh
alpha
bravo
./gautam.sh: line 13: cd: /non/existent/path: No such file or directory
charlie
./gautam.sh: line 14: cd: /non/existent/path: No such file or directory
--------------------------------------------------------------

答案 1 :(得分:1)

正如您所说,取消注释行cd /non/existent/path && gitk &将使它在后台运行-cd命令,并在成功运行后运行gitk命令。由于cd命令不成功,因为该路径不存在,所以将不执行gitk命令。如果希望独立于上一个命令执行此操作,请用;代替&&

当它在后台运行时,脚本会继续进行到打印阶段,只有在cpu进程转换为您在后台运行的进程时,脚本才会执行-启动后可能是10行,或者是5行,或者3行...没有合适的时间运行,因此您看到的行为是正常的。删除&将使其在脚本中顺序运行。

要将gitk作为后台进程启动并在最后显示该行,您可以在gitk实例化后执行一些sleep,但因为这样,它将始终返回错误{{1} }和cd由于gitk运算符而无法运行。