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

Ric*_*ard 11 bash scripts

我有一个 bash 源run.sh如下,

#!/bin/bash
if [ $# -ne 1 ]; then
    exit
fi
...
Run Code Online (Sandbox Code Playgroud)

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

source run.sh
Run Code Online (Sandbox Code Playgroud)

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

./run.sh
Run Code Online (Sandbox Code Playgroud)

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

更一般地说,我对为什么会发生这种情况感兴趣,以及使用“source”和“.”之间有什么区别。用于脚本执行?

And*_*ini 17

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

source run.sh
. run.sh
./run.sh
Run Code Online (Sandbox Code Playgroud)

前两行完全相同:.实际上是source. 什么source是在当前上下文中执行 shell 脚本,因此调用exit将退出 shell。

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


gei*_*rha 5

三种方式:

您可以将脚本包含在函数中并且仅使用 return。

#!/usr/bin/env bash
main() {
    ...
    return 1
    ...
}
main "$@"
Run Code Online (Sandbox Code Playgroud)

您可以测试脚本是否来自交互式 shell。

if [[ $- = *i* ]]; then
    return 1
else
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

您可以尝试返回,如果失败,则退出。

return 1 2>/dev/null || exit 1
Run Code Online (Sandbox Code Playgroud)