为什么我不能在Perl中使用system()获取命令的输出?

时间:2009-09-03 22:03:10

标签: perl ipc

在Perl的命令行上执行命令时,有没有办法将该结果存储为Perl中的变量?

my $command    = "cat $input_file | uniq -d | wc -l";
my $result     = system($command);

$result总是为0。

6 个答案:

答案 0 :(得分:10)

使用“反引号”:

my $command    = "cat $input_file | uniq -d | wc -l";
my $result     = `$command`;

如果对退出代码感兴趣,可以使用以下方法捕获它:

my $retcode = $?;
在进行外部通话后

答案 1 :(得分:6)

来自perlfaq8


为什么我不能用system()得到命令的输出?

你混淆了system()和反引号(````)的目的。 system()运行命令并返回退出状态信息(作为16位值:低7位是进程死亡的信号,如果有的话,高8位是实际退出值)。反引号(``)运行命令并返回它发送给STDOUT的内容。

$exit_status   = system("mail-users");
$output_string = `ls`;

答案 2 :(得分:3)

您可以使用Perl反向标记来运行shell命令,并将结果保存在数组中。

my @results = `$command`;

要从shell命令获取单个结果,可以将其存储在标量变量中:

my $result = `$command`;

如果您期望返回多行输出,则使用数组会更容易,但如果您只想要返回一行,则最好使用标量。

(类似的东西,我的perl生锈了)

答案 3 :(得分:1)

您可以像其他人所建议的那样使用反引号。如果您相信用于构建命令的任何变量,那就没问题。

为了获得更大的灵活性,您可以open将命令作为管道进行读取,并将其作为文件读取。当您想要将变量作为命令行参数传递给程序并且您不相信它们的源没有shell转义字符时,这尤其有用,因为最近的Perl(> = 5.8)中的open具有从参数列表调用程序的能力。所以你可以做到以下几点:

open(FILEHANDLE, '-|', 'uniq', 'some-file.txt') or die "Cannot fork: $!\n";
while (<FILEHANDLE>) {
    # process a line from $_
}
close FILEHANDLE or die "child error: $!\n";

答案 4 :(得分:1)

IPC :: System :: Simple提供'capture'命令,它提供了一种安全,便携的反引号替代方法。它(以及该模块的其他命令)强烈推荐。

答案 5 :(得分:0)

我假设这是一个“人为的”例子,因为这是 等价物:'uniq -d $ input_file | wc -l'。

在我的几乎所有经验中,结果的唯一原因 在perl变量中,是解析后来的。在那种情况下,我使用 以下模式:

$last = undef;
$lc = 0;
open(FN, "$input_file");
while (<FN>) {
   # any other parsing of the current line
   $lc++ if ($last eq $_);
   $last = $_;
}
close(FN);
print "$lc\n";

这也有额外的好处:

  • 没有shell for shell,cat,uniq和wc
  • 更快
  • 解析并收集所需的输入