以三种不同方式打开相同的脚本会产生三种不同的结果。为什么?

以三种不同方式打开相同的脚本会产生三种不同的结果。为什么?

我有一个示例脚本(信用归于科斯):

#!/bin/bash
cat <(cat /etc/lsb-release)

我将此脚本保存为某个名字在我的主目录中。

现在,我尝试用三种不同的方式打开此文件:

sh somename.sh

bash somename.sh

./somename.sh

因此,我有两个问题:

  1. 为什么尽管运行相同的脚本,上述命令的输出却不同?

    • 产生语法错误

    • 狂欢输出所需结果

    • ./给出权限被拒绝错误

  2. 为什么只有在使用以下命令运行脚本时才需要授予脚本可执行权限./在其他情况下则没有必要?

提前致谢!

编辑:第一部分可能类似于复制链接了一个,但我也有第二个问题。

答案1

正如我们在聊天中讨论的那样:

  1. sh script产生错误,因为直接调用解释器(在本例中sh)会忽略shebang,并且脚本在中运行shsh不支持进程替换(<([...])),这是Bash-isms,因此脚本在出错时退出。

    bash script不会产生错误,因为尽管 shebang 被忽略,但脚本仍然在 Bash 中运行,而 Bash 支持进程替换。

    ./scriptscript由于不可执行而产生错误。

  2. ./与您一起运行脚本必须在脚本上为您的用户设置执行位,这是操作系统的约束。

    所以问题实际上是:为什么不需要bash script为你的用户设置执行位script

    这是因为在运行bash script脚本时,Bash 会读取该脚本,而 Bash为您的用户设置的执行位。

    这意味着,拥有执行代码权限的 Bash 可以“绕过”操作系统对该脚本的限制,并且该脚本只需要可被 Bash 读取。

答案2

  • sh是 shell 的符号链接,并产生语法错误,因为语法中dash没有。它只在 bash 中存在(如果我没记错的话,在and中也存在)。<( . . .)shzshksh

  • bash 输出所需的结果,因为它的 bash 语法正确,没有任何错误

  • ./ 给出了一个权限被拒绝错误,因为你基本上说“嘿,shell,看看那个文件的权限,看看#!/bin/bash我的第一行(带有的那行)当前目录并弄清楚如何为我运行这个脚本”。 (旁注:如果你将脚本放在包含在变量中的位置$PATH,那么你只需运行就可以myScriptName.sh了,但想法是一样的,我们需要检查执行权限和要使用的解释器)

之前,您运行bashdash告诉它们从文件读取命令。这次bashdash是可执行的,而不是脚本。脚本现在是命令的来源,一个参数。始终为所有用户设置读取权限,因此 shell 将读取它。

答案3

总体来说shashdashbashcshtcshzsh... 都是具有自己语法和特征的 shell。它们之间有一些兼容性,但它们面向 [1]bashshell 将执行一个sh脚本,但并没有说明反之亦然。一次sh调用所需的资源比bash一次调用少。对于单个实例来说这不是问题,但对于数千个实例来说应该是问题。

执行方法。
要在 Linux 下将文件作为程序执行,无论它是脚本还是编译文件,都必须设置执行位 [2]并且它必须包含在您的$PATH.

如果它是一个脚本,它可以作为参数传递给相对 shell ( shbash... myfile.whatever):如果它被传递给错误的外壳你可能会得到一个不正确的行为,如果你幸运的话; 在这种情况下它不需要可执行因为这就像你直接在剧本里写台词一样在新壳中您正在调用。要在同一 shell 中执行,您可以使用source myfile. myfile,这相当于逐行写入在当前 shell 中脚本的内容。

地点
如果可执行程序不包含在您的路径中,您必须指定它的位置。

  • 就你的情况而言./意味着不仅你的shell的当前目录,也应该解决你的主目录中的~/myfile.whatever文件。myfile.whatever~/
  • 您可以从另一个位置调用它,例如使用/home/$USER/dir/myfile.whatever
  • 如果此文件位于路径中包含的目录中,则您可以使用简单的 来调用它myfile.whatever

如果多个可执行文件共享同一个名称,则指定完整路径将确保要执行哪个文件。 可以which mycommand告诉您现在将执行哪个文件(函数、别名、内置文件或路径中找到的第一个文件),但无法说明将来或由其他用户执行哪个文件。 如果您明确写出完整路径,则可以解决此歧义。 当同时安装多个程序时,执行程序的特定版本很有用...并避免木马。 在脚本中,始终建议写 而/bin/bash不是bash

相关内容