“调用为”指的是启动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
资源:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("I am %s\n", argv[0]);
return 0;
}
但是,要回答编号的问题...
(1&4)运行sh somescript将运行sh您身上的任何东西PATH,可能/bin/sh但可能类似/usr/xpg4/bin/sh。
- 如果它是Bash,则它会以POSIX模式运行,因为它会看到名称
sh。
- 如果是Z外壳或Korn外壳,则同样会看到名称
sh,但它以“ SH兼容”模式运行,该模式旨在与Bourne外壳兼容,并且在这两个外壳中均与完全POSIX兼容模式稍有不同。 。
- 当然,它可以是Almquist壳,实际的Bourne壳或其他东西。
(2&5)运行bash somescript将在常规Bash模式下运行(再次,当然,这取决于bash您所处的PATH状态。)
(3)在此,脚本名称直接代替程序文件提供给系统调用。内核读取hashbang行并使用它来运行脚本。
(6)这是复杂的。它类似于(3),但是ENOEXEC (Exec format error)由于没有hashbang行,用于启动程序的系统调用失败()。接下来发生的情况取决于您所运行的Shell 本身是否处于POSIX模式。POSIX要求POSIX兼容的shell以特定的方式响应ENOEXEC。 但是,“等效于调用shell的命令”中存在一些余地,这意味着不同的shell会执行不同的操作。
- “ Bourne Again”外壳将以脚本名称作为其第一个命令行参数的相同模式重新运行。在符合POSIX的模式下,它当然会以符合POSIX的模式运行,因此遵循POSIX要求来调用符合POSIX的shell。
- Z shell,Almquist shell和Korn shell
/bin/sh以在其他参数之前插入的脚本名称作为第一个命令行参数运行。Z外壳程序,Almquist外壳程序和Korn外壳程序(尝试)通过假定/bin/sh程序是一个来调用符合POSIX的外壳程序。