system
,exec
,open '|-'
,open2
等。所有这些都允许我将命令指定为要作为参数列表运行,并将其直接传递给{ {1}}而不是通过外壳运行。
即使execvp
足够聪明,如果它看起来像一个“简单”命令,也可以直接运行它,这免除了我用正确的shell换码并带有所有令人讨厌的陷阱的麻烦。
示例:
perl
代替
open my $out, '|-', $prog, @args;
system $prog, @args;
exec $prog, @args;
open my $out, "|$prog @args";
system "$prog @args";
exec "$prog @args";
运算符是否具有等效项?还是您必须始终手动完成此操作?
qx//
答案 0 :(得分:5)
模块IPC::System::Simple作为函数User.findAll({
...
order: [ [ Address, 'distance', 'DESC' ] ]
});
提供了qx运算符的列表形式(此外,与该模块中的其他函数一样,如果存在执行错误或非零响应代码,你可以调整)。另外,您可以使用Capture::Tiny来包装核心capturex
调用并提供相同的行为,但是它还具有可以将STDERR一起包装或与STDOUT分开包装的其他功能。
system
在芯管开放是在大多数情况下是唯一的选择,除了IPC::Open3这是类似的复杂但允许引导STDERR以及
答案 1 :(得分:5)
以下是一些简单的选项。
String::ShellQuote + qx
:
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote(@cmd);
my $output = `$cmd`;
use IPC::System::Simple qw( capturex );
my $output = capturex(@cmd)
use IPC::Run3 qw( run3 );
run3(\@cmd, \undef, \my $output);
use IPC::Run qw( run );
run(\@cmd, \undef, \my $output);
第一个解决方案涉及外壳,但没有其他解决方案。
答案 2 :(得分:0)
事实证明(不幸的是),这并不是我所忽略的-唯一的解决方案实际上是使用open -|
或使用其他答案中列出的外部模块之一。
反引号implementation(无论是由qx/.../
,`...`
还是readpipe
调用)在硬连线上可以接受单个字符串参数:
PP(pp_backtick)
{
dSP; dTARGET;
PerlIO *fp;
const char * const tmps = POPpconstx;
const U8 gimme = GIMME_V;
const char *mode = "r";
TAINT_PROPER("``");
if (PL_op->op_private & OPpOPEN_IN_RAW)
mode = "rb";
else if (PL_op->op_private & OPpOPEN_IN_CRLF)
mode = "rt";
fp = PerlProc_popen(tmps, mode);
...
请注意,POPpconstx
会从堆栈中弹出一个参数,并使用PerlProc_popen
而不是PerlProc_popen_list
。