为什么源(或点命令)不要求文件是可执行的

Tra*_*iet 3 shell shell-script

从跑步help .help source

从当前 shell 中的文件执行命令。

在当前 shell 中从 FILENAME 读取和执行命令。$PATH 中的条目用于查找包含 FILENAME 的目录。

从我的角度来看,似乎 dot 命令(或source命令)只是在当前 shell 上下文中运行一个 shell 脚本(而不是生成另一个 shell)。

问题:为什么.(或source)不要求文件像运行普通脚本一样可执行?

Phi*_*ing 6

假设我有一个 shell 脚本 ( my-script.sh) 开头:

#!/bin/sh
Run Code Online (Sandbox Code Playgroud)

如果脚本设置了执行权限,那么我可以使用以下命令运行脚本:

./my-script.sh
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您最终要求内核my-script.sh作为程序运行,内核(程序加载器)将首先检查权限,然后使用它/bin/sh ./my-script.sh来实际执行您的脚本。

但是 shell ( /bin/sh) 并不关心执行权限,也不检查它们。所以如果你调用这个...

/bin/sh ./my-script.sh
Run Code Online (Sandbox Code Playgroud)

... 内核永远不会被要求my-script.sh作为程序运行。内核(程序加载器)只需要运行/bin/sh. 所以我永远不会检查执行权限。也就是说,您不需要执行权限来运行这样的脚本。


回答你的问题:

你调用./my-script.sh. ./my-script.sh在另一个脚本中的区别是完全一样的。在第一种情况下,您要求内核将其作为程序运行,在第二种情况下,您要求当前的 shell 从脚本中读取命令,而 shell 不需要(或关心)执行此操作的权限。


进一步阅读:

仔细想想,将脚本作为程序运行是一种令人惊讶的行为。它们不是用机器代码编写的。我会详细了解为什么会这样;首先阅读shebang ( #!) https://en.wikipedia.org/wiki/Shebang_(Unix)

使用点符号运行脚本是共享变量所必需的。所有其他运行机制都会启动一个新的 shell“上下文”,这意味着在被调用脚本中设置的任何变量都不会被传递回调用脚本。Bash 文档有点精简,但它在这里:https : //www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html

  • @TranTriet 还要注意,使用`bash ./my-script.sh` 或`. ./my-script.sh`,shebang (`#!/bin/sh`) 将被完全忽略。在不同的壳之间交叉时,这可能是一个问题。 (2认同)