为什么shebang线总是第一线呢?

Vij*_*jay 20 unix perl solaris shebang

我有简单的perl脚本如下:

#!/usr/bin/perl

use strict;
use warnings;

print "hello world!\n";
Run Code Online (Sandbox Code Playgroud)

我可以执行如下脚本:

>temp.pl
hello world!
>
Run Code Online (Sandbox Code Playgroud)

如果我添加这样的评论:

#this script is just for test
#the shebang
#!/usr/bin/perl

use strict;
use warnings;

print "hello world!\n";
Run Code Online (Sandbox Code Playgroud)

当我尝试执行时,它给我输出如下:

> temp.pl
use: Command not found.
use: Command not found.
print: Command not found.
> 
Run Code Online (Sandbox Code Playgroud)

这里的重点是shebang line应该总是在顶部无论如何.但有人能解释我为什么吗?

Jen*_*ens 29

shebang必须是第一行,因为它由内核解释,内核查看可执行文件开头的两个字节.如果这些是行#!的其余部分被解释为要运行的可执行文件,并且脚本文件可用于该程序.(细节略有不同,但就是图片).

由于内核只会查看前两个字符并且没​​有其他行的概念,因此必须将哈希爆炸放在第1行中.

现在如果内核无法执行以#!whatever?开头的文件会发生什么?shell试图将可执行文件分叉并由内核通知它无法执行程序,作为最后的手段尝试将文件内容解释为shell脚本.由于shell不是perl,因此会出现一堆错误,与您尝试运行的错误完全相同

 sh < temp.pl
Run Code Online (Sandbox Code Playgroud)

  • ****DYNIX!它是在autoconf"便携式外壳"文档中.但是,似乎这个文档在2009年被更改/更正(我使用autoconf的工作是从1990年代后期开始的).http://web.archive.org/web/20080118164924/http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_chapter/autoconf_10.html(所以id****发生了!只是**没有**再发生.;-) (5认同)
  • 每个人都在说这个.但这是错误的.命名它或它没有发生:-) (2认同)

Sch*_*ern 7

除了上面的解释,这是中详细介绍了这里,并在这里这里有关于一些特殊的事情#!已经尚未提及和Perl.

Perl读取该#!行并执行两项操作.首先,如果路径看起来不像perl,它将使用它重新执行程序!例如...

#!/bin/sh

echo "Hello world!"
Run Code Online (Sandbox Code Playgroud)

如果执行,将正确运行perl /path/to/that/program.我不知道Perl做这个的历史原因,但是当你用Test :: Harness测试多种语言时它会派上用场.

第二件事是Perl #!在行中找到任何开关并将它们应用,就像它们在命令行上一样.这就是#!/usr/bin/perl -w打开警告的原因.

值得一提的是,与shebang处理的其他部分不同,这一切都是在Perl中完成的,而不是Unix,因此可以移植到Windows.

另一个Perl + shebang笔记是你可能在许多Perl程序的顶部找到的这种疯狂.

#!/usr/bin/perl

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
    if 0; # not running under some shell
Run Code Online (Sandbox Code Playgroud)

有时,在非常非常非常旧的系统上,它们#!不起作用,并且Perl程序由shell执行.该eval部队的外壳,以第一件事rexecute用Perl文件.由于shell语句在换行符结束时没有看到if 0.Perl确实看到了if 0,所以它不执行eval.Perl和shell都有语法上等效的eval运算符,这使得hack工作.

  • 这是上面的王室.请将显示器翻转以解决问题. (4认同)

Nor*_*ray 6

这不仅仅是它必须是第一行,字符#!必须是文件中的前两个字节.这可以运行脚本是一个shell功能,而不是一个OS功能,它并不特定于任何特定的脚本语言.

当系统被告知执行文件的内容时.../path/to/bin/program,或者通过PATH的类似路径,它会检查文件的前几个字节以查找显示文件类型的"幻数"它是(您可以使用file(1)命令查看该过程).如果它是一个已编译的二进制文件,那么它将以适当的方式加载并执行它,如果前两个字节是#!它将执行'shebang-hack'.

'shebang-hack'是一种特殊情况,被一些shell使用(事实上,基本上每一个,但它是常规而不是要求),其中shell将剩余字节读取到换行符,将它们解释为文件名,然后执行该文件,将其余的当前文件作为输入.还有一些你可以在其他地方读到的细节.

一些(版本的)shell将允许相当长的第一行,一些允许只有短行; 一些允许多个参数,一些只允许一个参数.

如果文件不是#!以文本开头,但看起来确实是文本,那么一些shell会启发式尝试执行它.Csh(如果我没记错的话)对它是一个csh脚本,并且如果第一行是空白的,生命太短暂不能记住,那么有一些复杂而神秘的案例要处理一些shell的行为.

Sven Mascheck的#中有一些有趣且广泛的细节(以及准确的细节,因为它们与我的回忆相符!)!页面.

  • 它不是shell功能,而是OS功能. (5认同)