Answers:
在回答之前,我认为需要进行一些澄清。让我们分析以下三行:
source run.sh
. run.sh
./run.sh
前两行完全相同:.
实际上是的别名source
。是什么source
做的是执行shell脚本在当前情况下,因此调用exit
将退出外壳。
但是,第三行(使您感到困惑的那条)与其他行无关。./run.sh
只是一条路径,与(例如)/home/user/run.sh
或相同/usr/bin/something
。始终记住,shell中的命令用空格隔开。因此,在这种情况下,该命令不是.
,而是./run.sh
:这意味着将执行一个子外壳程序,并且该命令exit
仅对子外壳程序有效。
三种方式:
您可以将脚本包含在函数中,并且只能使用return。
#!/usr/bin/env bash
main() {
...
return 1
...
}
main "$@"
您可以测试脚本是否由交互式外壳程序提供。
if [[ $- = *i* ]]; then
return 1
else
exit 1
fi
您可以尝试返回,如果失败,则退出。
return 1 2>/dev/null || exit 1
-
保存当前活动的选项标志。该测试检查该-i
标志是否处于活动状态。参见gnu.org/software/bash/manual/html_node/Special-Parameters.html
将命令“源”视为“包含”语句中的内容。它接受参数的内容并像直接运行该参数一样运行它。在这种情况下,您的命令是“源”,参数为“ run.sh”,并且将完全像在命令行中键入run.sh的内容一样执行run.sh。
当您运行“ ./run.sh”时,“ ./ run.sh”是您的命令,并且没有参数。由于此文件是纯文本而不是二进制文件,因此您的外壳程序会在shebang(第一行的“#!”)中寻找解释器,并找到“ / bin / bash”。因此,您的外壳程序随后将启动一个新的bash实例,并且run.sh的内容将在该新实例中运行。
在第一种情况下,当bash到达“ exit”命令时,它的执行就像您在命令行中键入的一样。在第二个实例中,它是在您的shell启动的bash进程中执行的,因此,只有此bash实例会收到一个“退出”命令。
当您在bash中键入一行时,将第一个空格之前的所有内容视为命令,并将其后的所有内容视为参数。命令 '。' 是“源”的别名。当您运行'。run.sh'的'。是一个命令,因为它与参数之间用空格隔开。当您运行“ ./run.sh”时,您的命令是“ ./run.sh”和“。” 是带有'。'的run.sh相对路径的一部分。代表您当前的文件夹。
$- = *i*
?