“ source x”,“。”和有什么区别?Bash中的“ x”和“ ./x”?


11

我有一个bash来源run.sh,如下所示:

#!/bin/bash
if [ $# -ne 1 ]; then
    exit
fi
...

当我以两种方式执行它时,会有不同的行为。第一种方法是

source run.sh

执行后将关闭终端。第二种方式是

./run.sh

这将简单地完成脚本的运行,并停留在终端上。我问是否有用于退出对既有的bash脚本命令source run.sh./run.sh执行。我也尝试return过,在./run.sh执行下效果不佳。

更笼统地说,我对为什么发生这种情况以及使用“源”和“源”之间的区别感兴趣。用于脚本执行?

Answers:


16

在回答之前,我认为需要进行一些澄清。让我们分析以下三行:

source run.sh
. run.sh
./run.sh

前两行完全相同:.实际上是的别名source。是什么source做的是执行shell脚本在当前情况下,因此调用exit将退出外壳。

但是,第三行(使您感到困惑的那条)与其他行无关。./run.sh只是一条路径,与(例如)/home/user/run.sh或相同/usr/bin/something。始终记住,shell中的命令用空格隔开。因此,在这种情况下,该命令不是.,而是./run.sh:这意味着将执行一个子外壳程序,并且该命令exit仅对子外壳程序有效。


5

三种方式:

您可以将脚本包含在函数中,并且只能使用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*
deadbeef404 '16

@ deadbeef404特殊参数-保存当前活动的选项标志。该测试检查该-i标志是否处于活动状态。参见gnu.org/software/bash/manual/html_node/Special-Parameters.html
geirha,2016年

1

将命令“源”视为“包含”语句中的内容。它接受参数的内容并像直接运行该参数一样运行它。在这种情况下,您的命令是“源”,参数为“ 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相对路径的一部分。代表您当前的文件夹。


如果您是C / C ++程序员,希望通过shell / bash脚本获得更好的结果,那么这是一个完美的答案。
贾斯汀
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.