bash 脚本如何通过其文件名作为命令名执行,带或不带 shebang?

bash 脚本如何通过其文件名作为命令名执行,带或不带 shebang?

来自 bash 手册:

3.7.2 命令查找与执行

将命令拆分为单词后,如果生成简单命令和可选参数列表,则将执行以下操作。

...

  1. 如果该名称既不是 shell 函数也不是内置函数,并且不包含斜杠,Bash 将搜索 $PATH 的每个元素以查找包含该名称的可执行文件的目录。

  2. 如果搜索成功,或者命令名称包含一个或多个斜杠,则 shell 会在单独的执行环境中执行指定的程序。参数 0 设置为给定的名称,命令的其余参数设置为提供的参数(如果有)。

  3. 如果由于文件不是可执行格式且文件不是目录而导致执行失败,假设它是一个 shell 脚本shell 按照第 39 页第 3.8 节 [Shell 脚本] 中所述执行它。

  1. 假设 bash 脚本myscript不包含 shebang。

    • 引用是否意味着如果脚本通过命令在 bash 中执行myscript,那么

      • bash 首先会假设它是一个 ELF 并调用execve()它,因为它是一个 bash 脚本而不是 ELF,所以execve()调用会失败,

      • bash 接下来会执行bash myscript吗?

    • 与通过 in bash 运行 bash 脚本相比bash myscript,通过 in bash 运行脚本myscript还会直接调用execve()脚本失败吗?

    • 如果是,则myscript慢于bash myscript?为什么 ”Linux 命令、编辑器和 Shell 编程实用指南 作者:Mark G. Sobell“说反话?

      虽然您可以使用 bash 来执行 shell 脚本,但这种技术会导致脚本运行速度比授予自己执行权限并直接调用脚本更慢。

  2. 如果 bash 脚本myscript包含 shebang #! /bin/bash,当它通过命令在 bash 中执行时myscript

    • 它的执行方式与通过命令在 bash 中执行的方式相同吗bash myscript

    • 它的执行方式是否与从脚本中删除 shebang 然后通过命令执行脚本相同myscript

谢谢。

我的帖子的灵感来自像可执行文件一样运行脚本与通过 shell 显式运行它有何不同?哪个 shell 解释器运行不带 shebang 的脚本?

答案1

    • 引用是否意味着如果通过命令 myscript 在 bash 中执行脚本,那么

      • bash 首先会假设它是一个 ELF 并调用execve()它,因为它是一个 bash 脚本而不是 ELF,所以execve()调用会失败,

      如果 Bash 找到一个可执行文件,它首先会假设它是操作系统可以执行的某种格式,然后呼吁execve。如果成功,这仍然可能不是 ELF 或其他本机可执行文件。例如,Linux 的binfmt_misc功能允许许多其他可执行格式可以运行。在这种特殊情况下,execve调用很可能会失败。

      • bash 接下来会执行bash myscript吗?

      Bash 将使用其现有的子进程来执行其中的脚本,并根据需要重新初始化 shell 环境。没有启动或exec调用其他进程。

    • 与在 bash 中通过 bash myscript 运行 bash 脚本相比,在 bash 中通过 myscript 运行脚本还会直接调用execve()脚本失败吗?

      是的,我想是的,如果你的意思是“失败的呼叫”。

    • 如果是,则myscript慢于bash myscript?为什么“Mark G. Sobell 的 Linux 命令、编辑器和 Shell 编程实用指南”的说法相反?

      虽然您可以使用 bash 来执行 shell 脚本,但这种技术会导致脚本运行速度比授予自己执行权限并直接调用脚本更慢。

      bash考虑到现行的诽谤法,我不会评论该问题的第二部分,但即使是几次失败的库和系统调用,与启动整个过程然后再进行比较也不会产生可衡量的差异口译一个脚本。我无法访问相关页面来查找您可能错过的任何上下文。然而,几乎可以肯定,它不是在讨论无事可做的案件。

  1. 如果 bash 脚本myscript包含 shebang #! /bin/bash,当它通过命令在 bash 中执行时myscript

    • 它的执行方式与通过命令在 bash 中执行的方式相同吗bash myscript

    是的;在一种情况下,由子进程直接bash myscript编辑exec,而在另一种情况下,系统一旦找到 shebang 行exec就会编辑。/bin/bash myscript

    • 它的执行方式是否与从脚本中删除 shebang 然后通过命令执行脚本相同myscript

    就您可以合理检测到的范围而言,是的。这些都不重要。严格来说,在这种情况下,main()的函数bash不会再次运行,因为子进程只是在内部重新初始化自身,并且它确实在其他情况下运行。如果您真的很热衷的话,您可以构建一个场景,其中这很重要,但这不值得付出努力。

请注意,这是一个 Bash 功能,并且sh其他 shell 使用或其他 shell执行 shebangless 脚本,而不是其中之一bash或它们本身,如您链接的另一个问题中所述。我们还假设您的交互式 shellbash与 shebang 行中的交互式 shell 相同。

相关内容