shell脚本仍然可以在没有#的情况下工作!(sha-bang行)


10

我是shell脚本的新手,很多书都写过在脚本开始时使用#!(sha-bang)行来调用解释器,这将为脚本调用新的shell并逐行进行解释。我的基本脚本仍然没有魔术般运行。

所以我的问题是:

  • 我的基本脚本是从哪里得到解释器的。
  • 脚本如何设法找到解释器。

现在,让我告诉您我的基本脚本,它仅包含以下行:

回声“没有魔力的基本剧本”


Answers:


3

如果未提供魔术线,则使用默认外壳程序运行脚本。此默认Shell可以是Bourne Shell(sh),在某些版本中就是这种情况,但是,在某些其他版本中,所使用的默认Shell与执行它的登录Shell相同。关键是:不要将其留给系统来决定外壳,始终在第一行中提供所需的外壳。


1
是的..可能是我当前的外壳正在为没有魔术数字的外壳脚本调用默认外壳。
user1678213 '10 -10-10

1
@ user1678213是的,这是您的外壳程序(而不是内核)执行的。
吉尔(Gilles)'所以

1
我相信POSIX要求在这种情况下使用/ bin / sh。
vonbrand 2013年

2
@vonbrand这是一个常见的误解。POSIX并不要求POSIX shell是/bin/sh,而只是成为sh探索一致PATH时发现的第一个可执行文件。
jlliagre

3
那是不正确的,它绝不是用于执行它的“登录外壳”。但是,可能发生的情况是,调用外壳程序(如果脚本是从外壳程序调用的)可能会有一个自己的子进程来解释它。
斯特凡Chazelas

8

当您执行程序时,内核会检查它是否以某种魔术字节序列开始。如果可执行文件以开头#!,则内核会将其余行解释为解释器名称。如果可执行文件以\177ELF\177以127字节为开头)开头,则它将文件作为ELF可执行文件加载;如今,这是大多数Unix系统上的正常类型。

如果内核无法识别文件格式,则它拒绝执行文件并返回错误ENOEXEC(执行格式错误)。当shell注意到这一点时,它将自己作为shell脚本执行程序。

为了证明这一点,请在脚本中添加一些命令:

ps l $$
ls -l /proc/$$/exe
echo hello

(这是针对Linux的,请针对其他unice进行调整。)然后尝试从各种shell运行该脚本。您会看到一些shell生成了自己的新实例来执行脚本(bash,ksh93),而另一些则生成了/bin/sh(dash,pdksh,zsh)。


我用您的ls -l命令寻找什么?这:lrwxrwxrwx 1 i 0 Oct 11 05:15 exe -> /bin/bash-?如果是这样,它怎么说?另外,请注意我已经SHELL=/bin/bash启用env,但是更改它似乎并没有改变行为。也许是无关的?
伊曼纽尔·伯格

似乎您正在更改外壳程序变量“ SHELL”。如果是,那么您仅更改外壳程序变量SHELL的值。它不会更改您的shell。要更改您的外壳程序,请编辑/ etc / passwd文件。
user1678213 '10 -10-11

2
@EmanuelBerg是的(ls -l /proc/$$/exe实际上我应该写过)。该exe链接指向负责执行脚本的外壳。运行脚本时,您会看到解释脚本的是bash。如果从例如pdksh运行它,它将运行/bin/shSHELL在这种情况下,我不知道任何使用环境变量的外壳程序或登录外壳程序。
吉尔(Gilles)'所以

2
@ user1678213更改外壳将/etc/passwd更改通过SSH或在文本控制台上登录时执行的外壳。它不会更改哪个外壳程序可以执行脚本。
吉尔(Gilles)'所以

2
@ user1678213我通过运行测试验证了我在这里写的内容。我测试过的所有/etc/passwdshell都不用决定使用哪个shell,它们要么派生自己的实例,要么执行/bin/sh
吉尔斯(Gillles)“所以-别再作恶了”

-2

它可能是以下三种可能性之一:

  1. 您正在直接使用解释器IE调用脚本:bash script.sh

  2. 脚本文件的名称带有.sh扩展名,它使系统可以查找此类文件的默认程序。

  3. 因为我只能猜测脚本文件是可执行的,所以您正在使用的shell环境正在单独执行“ echo”。例如,如果您将使用bash shell并且在文件中有仅由ksh使用的命令,那么您将看到它将不起作用。

祝好运!


3
我既没有用bash也没有任何扩展名来称呼它。
user1678213 '10 -10-10

1
和外壳环境不执行它,因为当我在调用脚本后调用ps命令时。ps命令显示了两个bash进程。这意味着有两个bash正在运行。一个是我的登录bash shell,另一个是我的basic_script的bash
user1678213 2012年

1
2:内核不会做任何事情。Zsh可以做到,bash可以扭曲为做到这一点。3:是的,但是各个外壳之间的差异会有所不同,请参阅我的答案。
吉尔(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.