我在这个问题中阅读了以下内容:
bash 支持 --posix 开关,这使其更符合 POSIX 标准。如果作为 sh 调用,它还会尝试模仿 POSIX 。
上面的引用假定/bin/sh是指向 的链接/bin/bash。
但我不太明白“作为 sh 调用”是什么意思。
假设我有以下名为“script.sh”的脚本:
#!/bin/bash
echo "Hello World"
Run Code Online (Sandbox Code Playgroud)
请在以下每种情况下告诉我脚本是在正常bash模式下还是在 POSIX 模式下运行(假设我在正在运行的终端中执行了以下命令bash):
sh script.shbash script.sh./script.sh现在说我有以下脚本,称为“script.sh”(类似于上面的脚本,但没有shebang):
echo "Hello World"
Run Code Online (Sandbox Code Playgroud)
请在以下每种情况下告诉我脚本是在正常bash模式下还是在 POSIX 模式下运行(假设我在正在运行的终端中执行了以下命令bash):
sh script2.shbash script2.sh./script2.shMic*_*mer 19
只有情况 1 和 4 将在 POSIX 模式下运行(假设sh是 bash 而不是 sh 的其他一些实现)。任何明确调用bashwithout 的情况--posix都不会,无论是否来自 shebang。任何明确调用的情况sh都会。shebang 仅在没有为脚本显式启动 shell 时使用。
第 6 种情况,如果您的终端正在运行bash,则不会在 POSIX 模式下运行,Bash 将使用自身调用它。如果你的终端是不是运行的zsh,案例6将同时在POSIX模式下运行。POSIX 对于在那种情况下到底应该发生什么是模棱两可的,而 Bash 和 zsh 在那里做出了不同的选择。Bash 使用自身调用脚本,而 zsh 使用sh(无论发生什么)。其他贝壳在这一点上也有所不同。
判断您处于哪种模式的一种简单方法是制作脚本主体:
kill -SIGHUP
Run Code Online (Sandbox Code Playgroud)
这将在 POSIX 模式下失败并出现错误,但给出kill它之外的使用说明。这是一个简单的区别,它适用于您可能遇到的各种 Bash 版本。
“调用为”是指启动 Bash 的进程放入其“第零个”命令行参数argv[0].
当程序以exec*()syscalls启动时,它们并没有真正了解包含该程序的二进制文件的名称,而是调用进程可以自由地将它想要的任何内容放入其中。通常,当然,名称取自文件系统,因此如果您运行/bin/sh,这就是放在那里的内容。如果/bin/sh是 Bash,它不必是符号链接,它可以是硬链接或只是 shell 程序的另一个副本。
作为设置“程序名称”的示例,Bash 的exec命令可以使用-a选项设置第零个参数。(我们可以用 Perl 做同样的事情,或者直接用 C 等等。)
这myname是一个简单的 C 程序,它只打印第零个参数,即它自己看到的名称:
$ ./myname
I am ./myname
$ (exec -a something ./myname )
I am something
$ mv ./myname somename
$ ln -s somename othername
$ ./somename
I am ./somename
$ ./othername
I am ./othername
Run Code Online (Sandbox Code Playgroud)
来源:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("I am %s\n", argv[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,要回答编号的问题......
(1&4)运行sh somescript将运行什么sh是你的PATH,大概/bin/sh但可能类似/usr/xpg4/bin/sh。
sh. sh,但它以“SH 兼容”模式运行,该模式旨在与 Bourne shell 兼容,并且与这两种 shell 中的完全 POSIX 兼容模式略有不同. (2 & 5) Runningbash somescript将在常规 Bash 模式下运行(同样,这当然取决于bash您的PATH情况。)
(3) 这里,脚本的名称直接提供给系统调用而不是程序文件。内核读取 hashbang 行并使用它来运行脚本。
(6) 这是一个复杂的问题。它类似于(3),但启动程序的系统调用失败(ENOEXEC (Exec format error)),因为没有 hashbang 行。接下来会发生什么取决于您正在运行的 shell本身是否处于 POSIX 模式。POSIX 要求符合 POSIX 的 shell 以特定方式响应ENOEXEC. 然而,在“相当于调用 shell 的命令”中有一些余地,这意味着不同的 shell 做不同的事情。
/bin/sh使用在其他参数之前插入的脚本名称作为其第一个命令行参数运行。Z shell、Almquist shell 和 Korn shell 正在(试图)通过假设/bin/sh程序是一个来调用符合 POSIX 的 shell 。