我观察到有两种执行 perl 程序的方法:
perl test.pl
和
./test.pl
这两者之间的确切区别是什么,哪一个是值得推荐的?
我会稍微改一下其他答案所说的内容。
第一种情况将运行名为“perl”的程序——大概是一个 Perl 语言解释器,并将值“test.pl”作为第一个参数传递给它。请注意,这将执行以下三件事之一,具体取决于“perl”是什么以及“test.pl”是什么:
$PATH
如果“perl”在您的或 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 将失败并出现“command not found”错误。
如果文件设置了执行位,shell(或者实际上是 Unix 内核中的进程加载器)将尝试执行它。Unix 执行给定可执行文件的规则由文件的前 2 个字节控制,也就是“幻数”。
有关幻数如何工作的非常好的深入报道,请参阅How does the #! work?
SO 上的“”问题。
在“幻数”为“#!”的特殊情况下 (又名“shebang”),加载程序将读取文件的第一行,并将该行的内容(无前 2 个字节)视为要运行的命令,而不是给定的可执行文件;并将可执行文件的路径作为另一个参数附加到它从 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;
(或任何其他它不知道如何处理的前 2 个字节),它要么会出错,要么(至少在 RedHat Linux 上)会假装在那里是一个隐含的#!/bin/sh
shebang,并尝试将文件作为 Bourne Shell 脚本执行。这当然会失败,因为它是 Perl 代码,而不是 shell 脚本
在第一种情况下,您正在启动perl
解释器并要求它使用您的文件并运行它。
在第二种情况下,您要求您的 shell 执行您的文件。这要求文件以
#!/<path to perl>/perl
并且该文件设置了执行位。
最好的使用方法是最适合您的用例的方法。
第一个将始终将脚本作为perl
代码运行。
只有在 she-bang 中指定了 perl 的情况下,第二个才会这样做。否则,它将作为 shell 代码或 she-bang 中指定的任何内容运行(如果根本没有 she-bang,它将作为当前 shell 代码运行)。
noexec
即使启用了挂载选项,也会执行第一个。
在这种情况下,第二个将失败。
与执行位相同的东西。+x
如果未设置,第一个将起作用,第二个将失败。
第一个使用perl
在您的$PATH
. 第二个使用程序中所说的任何shebang行。
如果你设置了文件的可执行权限,那么你可以通过./运行文件,或者使用perl filename.pl运行
perl 测试.pl
./test.pl