您当前的 perl 解释器的位置可以在特殊变量中找到$^X
。如果 perl 不在您的路径中,或者如果您有多个 perl 版本可用,但要确保您使用的是同一个版本,这一点很重要。
在执行包括其他 Perl 程序在内的外部命令时,确定它们是否实际运行是相当困难的。检查$?
会留下持久的心理创伤,所以我更喜欢使用IPC::System::Simple(可从 CPAN 获得):
use strict;
use warnings;
use IPC::System::Simple qw(system capture);
# Run a command, wait until it finishes, and make sure it works.
# Output from this program goes directly to STDOUT, and it can take input
# from your STDIN if required.
system($^X, "yourscript.pl", @ARGS);
# Run a command, wait until it finishes, and make sure it works.
# The output of this command is captured into $results.
my $results = capture($^X, "yourscript.pl", @ARGS);
在上述两个示例中,您希望传递给外部程序的任何参数都进入@ARGS
. 在上面的两个示例中也避免了 shell,这给您带来了一点速度优势,并避免了涉及 shell 元字符的任何不必要的交互。上面的代码还期望你的第二个程序返回一个零退出值来表示成功;如果不是这种情况,您可以指定允许退出值的附加第一个参数:
# Both of these commands allow an exit value of 0, 1 or 2 to be considered
# a successful execution of the command.
system( [0,1,2], $^X, "yourscript.pl", @ARGS );
# OR
capture( [0,1,2, $^X, "yourscript.pl", @ARGS );
如果您有一个长时间运行的进程,并且您希望在生成数据时对其数据进行处理,那么您可能需要一个管道打开,或者来自 CPAN 的更重量级的 IPC 模块之一。
说了这么多,任何时候你需要从 Perl 调用另一个 Perl 程序,你可能希望考虑使用模块是否是一个更好的选择。启动另一个程序会带来相当多的开销,无论是在启动成本方面,还是在进程之间移动数据的 I/O 成本方面。这也大大增加了错误处理的难度。如果你能把你的外部程序变成一个模块,你会发现它简化了你的整体设计。
祝一切顺利,
保罗