我注意到有两种执行perl程序的方法:
perl test.pl
并且
./test.pl
这两者的确切区别是什么,哪个更值得推荐?
我注意到有两种执行perl程序的方法:
perl test.pl
并且
./test.pl
我稍微改述一下其他答案的陈述。
第一种情况会运行名为"perl"的程序-可能是Perl语言解释器,并将值"test.pl"作为第一个参数传递给它。请注意,这将根据"perl"和"test.pl"的具体情况有三种可能的结果:
如果"perl"在您的$PATH
中不存在可执行文件或者不是shell别名(可以通过运行which perl
来检查),则您的shell会尝试找到不存在的可执行文件,并因出现perl: Command not found
错误而失败。
如果"perl"是您路径中的可执行文件(或shell别名),但实际上并不是Perl解释器程序,则会执行该文件。例如,在csh中尝试以下操作:
alias perl echo
which perl # Will print "perl: aliased to echo"
perl test.pl # Will print "test.pl". NOT what you intended!
unalias perl
这将执行你的 "perl" 别名,并简单地回显单词 "test.pl"。
如果 "perl" 是你的路径中存在一个真实的 Perl 解释器,它会将 "test.pl" 作为第一个参数传递给它。在这种情况下,Perl 解释器将把这个参数(因为它不以 "-" 开头)看作是要执行的包含 Perl 代码的文件名,并尝试读取该文件,将其编译为 Perl 代码并执行它。
请注意,由于实际运行的程序是 "perl",而 "test.pl" 只是一个被读入的文本文件,因此 "test.pl" 不需要具有“执行”Unix 文件权限。
第二种情况是,shell 将尝试在当前目录中找到一个名为 "test.pl" 的文件,并且 - 如果它存在并且可执行 - 尝试将其作为程序执行。
如果文件不存在或者没有设置执行权限,则 shell 将出现“命令未找到”的错误。
如果文件已经设置了执行权限,shell(或实际上是 Unix 内核中的进程加载器)将尝试执行它。Unix 执行给定可执行文件的规则由文件的前两个字节,即“magic number”来控制。
有关魔数如何工作的非常详细的覆盖,请参见 SO 上的“How does the #! work?
”问题。
在特殊情况下,如果“magic number”是“#!”(也称为“shebang”),加载器将读取文件的第一行,并将该行的内容(去掉前两个字节)视为一个要运行的命令,而不是所给出的可执行文件; 并将可执行文件的路径添加为它从 shebang 行中读取的命令的另一个参数。例如:
如果 “test.pl” 是一个带有第一行 #!/bin/sh -x
的文本文件,则内核将执行 /bin/sh -x ./test.pl
。
如果 "test.pl" 是一个带有第一行 #!/usr/bin/perl
的文本文件,则内核将执行 /usr/bin/perl ./test.pl
。
如果 "test.pl" 是一个带有第一行 #!perl
的文本文件,则内核将执行 perl ./test.pl
。
如果 “test.pl” 是一个带有第一行 my $var = 1;
(或任何其他它不知道如何处理的前两个字节)的文本文件,则它将错误地退出或(至少在 RedHat Linux 上)假装有一个隐含的 #!/bin/sh
shebang 并尝试将文件作为 Bourne Shell 脚本执行。这当然会失败,因为它是 Perl 代码,而不是 shell 脚本。
perl
解释器并要求它使用您的文件并运行它。#!/<path to perl>/perl
同时确保该文件具有可执行权限,这是使用最佳方法的前提条件。
最好的方法是选择适合您用例的方法。
第一个将始终作为perl
代码运行。
第二个仅在she-bang中指定了perl时才会这样做。否则,它将作为shell代码或she-bang中指定的任何内容运行(如果没有she-bang,它将作为当前shell代码运行)。
即使启用了noexec
挂载选项,第一个也将被执行。
在这种情况下,第二个会失败。
执行位也是如此。如果未设置+x
,第一个将起作用,而第二个将失败。
perl test.pl
./test.pl