shell 脚本中的指令顺序

Order of instructions in shell script

我有这个简单的 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 作为后台进程启动,但最后仍然出现带有破折号的行?

正如您所说,取消注释行 cd /non/existent/path && gitk & 将导致它在后台 运行 - cd 命令,并且在 运行 成功后,gitk 命令。由于cd命令没有成功,因为路径不存在,所以gitk命令不会执行。如果您希望它独立于之前的命令执行,请将它们拆分为 ; 而不是 &&

由于它 运行 在后台运行,脚本会继续到打印阶段,只有当 cpu 进程切换到您 运行 在后台运行的进程时,脚本才会执行 -它启动后可能是 10 行,或 5 行,或 3 行......它没有正确的时刻 运行,所以你看到的行为是正常的。删除 & 将使其在脚本中按顺序 运行。

要启动 gitk 作为后台进程并让该行出现在最后,您可以在 gitk 实例化后做一些 sleep,但它总是 return由于 && 运算符,cdgitk 的错误不会 运行。

行为符合预期,因为您通过 & 生成了一个子进程。如果你想在你的脚本末尾添加 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
--------------------------------------------------------------