如何从 Perl 脚本中运行 Perl 脚本? [英] How do I run a Perl script from within a Perl script?

查看:33
本文介绍了如何从 Perl 脚本中运行 Perl 脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要执行另一个 Perl 脚本的 Perl 脚本.第二个脚本可以直接在命令行上执行,但我需要从我的第一个程序中执行它.我需要向它传递一些参数,这些参数通常会在它独立运行时传入(第一个脚本定期运行,并在一组特定的系统条件下执行第二个脚本).

I've got a Perl script that needs to execute another Perl script. This second script can be executed directly on the command line, but I need to execute it from within my first program. I'll need to pass it a few parameters that would normally be passed in when it's run standalone (the first script runs periodically, and executes the second script under a certain set of system conditions).

初步的 Google 搜索建议使用反引号或 system() 调用.有没有其他方法可以运行它?(我猜是的,因为我们正在谈论的是 Perl :P)如果我需要从被调用的程序中捕获输出,哪种方法是首选(并且,如果可能,将输出通过管道传输到标准输出,就像第二个一样程序被直接调用)?

Preliminary Google searches suggest using backticks or a system() call. Are there any other ways to run it? (I'm guessing yes, since it's Perl we're talking about :P ) Which method is preferred if I need to capture output from the invoked program (and, if possible, pipe that output as it executes to stdout as though the second program were invoked directly)?

(哦,现在 SO 提出了一些相关问题.这个很接近,但与我要问的不完全一样.第二个程序可能需要一个小时或更长时间才能运行(很多 I/O),所以我不确定一次性调用是否适合于此.)

( oh, now SO suggests some related questions. This one is close, but not exactly the same as what I'm asking. The second program will likely take an hour or more to run (lots of I/O), so I'm not sure a one-off invocation is the right fit for this.)

推荐答案

可以在特殊变量 $^X 中找到当前 perl 解释器的位置.如果 perl 不在您的路径中,或者您有多个 perl 版本可用,但要确保您全面使用相同的版本,这一点很重要.

The location of your current perl interpreter can be found in the special variable $^X. This is important if perl is not in your path, or if you have multiple perl versions available but which to make sure you're using the same one across the board.

在执行外部命令(包括其他 Perl 程序)时,确定它们是否真正运行是非常困难的.检查 $? 会留下持久的心理创伤,所以我更喜欢使用 IPC::System::Simple(可从 CPAN 获得):

When executing external commands, including other Perl programs, determining if they actually ran can be quite difficult. Inspecting $? can leave lasting mental scars, so I prefer to use IPC::System::Simple (available from the 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 元字符的不需要的交互.上面的代码还期望你的第二个程序返回一个零退出值来表示成功;如果不是这种情况,您可以指定允许退出值的附加第一个参数:

In both of the above examples any arguments you wish to pass to your external program go into @ARGS. The shell is also avoided in both of the above examples, which gives you a small speed advantage, and avoids any unwanted interactions involving shell meta-characters. The above code also expects your second program to return a zero exit value to indicate success; if that's not the case, you can specify an additional first argument of allowable exit values:

 # 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 );

如果您有一个长时间运行的进程,并且您想在生成数据时处理它,那么您可能需要一个管道打开,或者更重量级的 IPC 模块之一来自 CPAN.

If you have a long-running process and you want to process its data while it's being generated, then you're probably going to need a piped open, or one of the more heavyweight IPC modules from the CPAN.

话虽如此,任何时候您需要从 Perl 调用另一个 Perl 程序时,您可能希望考虑使用模块是否是更好的选择.启动另一个程序会带来相当多的开销,包括启动成本和在进程之间移动数据的 I/O 成本.这也大大增加了错误处理的难度.如果你能把你的外部程序变成一个模块,你可能会发现它简化了你的整体设计.

Having said all that, any time you need to be calling another Perl program from Perl, you may wish to consider if using a module would be a better choice. Starting another program carries quite a few overheads, both in terms of start-up costs, and I/O costs for moving data between processes. It also significantly increases the difficulty of error handling. If you can turn your external program into a module, you may find it simplifies your overall design.

一切顺利,

保罗

这篇关于如何从 Perl 脚本中运行 Perl 脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆