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)
除了上面的解释,这是中详细介绍了这里,并在这里和这里有关于一些特殊的事情#!已经尚未提及和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工作.
这不仅仅是它必须是第一行,字符#!必须是文件中的前两个字节.这可以运行脚本是一个shell功能,而不是一个OS功能,它并不特定于任何特定的脚本语言.
当系统被告知执行文件的内容时.../path/to/bin/program,或者通过PATH的类似路径,它会检查文件的前几个字节以查找显示文件类型的"幻数"它是(您可以使用file(1)命令查看该过程).如果它是一个已编译的二进制文件,那么它将以适当的方式加载并执行它,如果前两个字节是#!它将执行'shebang-hack'.
'shebang-hack'是一种特殊情况,被一些shell使用(事实上,基本上每一个,但它是常规而不是要求),其中shell将剩余字节读取到换行符,将它们解释为文件名,然后执行该文件,将其余的当前文件作为输入.还有一些你可以在其他地方读到的细节.
一些(版本的)shell将允许相当长的第一行,一些允许只有短行; 一些允许多个参数,一些只允许一个参数.
如果文件不是#!以文本开头,但看起来确实是文本,那么一些shell会启发式尝试执行它.Csh(如果我没记错的话)对它是一个csh脚本,并且如果第一行是空白的,生命太短暂不能记住,那么有一些复杂而神秘的案例要处理一些shell的行为.
在Sven Mascheck的#中有一些有趣且广泛的细节(以及准确的细节,因为它们与我的回忆相符!)!页面.