perl反引号中使用的尾部命令

时间:2015-03-25 21:39:22

标签: perl unix command backticks

我正在尝试使用通常的反引号在perl脚本中运行tail命令。

我的perl脚本中的部分如下:

$nexusTime += nexusUploadTime(`tail $log -n 5`);

所以我试图获取此文件的最后5行,但是当perl脚本完成时我收到以下错误:

sh: line 1: -n: command not found

即使我在命令行上运行命令它确实成功了,我可以看到该特定的5行。

不确定这里发生了什么。为什么它可以从命令行运行,但是通过perl它将无法识别-n选项。

有人有什么建议吗?

3 个答案:

答案 0 :(得分:5)

$log有一个无关的尾随换行符,因此您正在执行

tail file.log
 -n 5            # Tries to execute a program named "-n"

修正:

chomp($log);

请注意,如果log $log包含shell元字符(例如空格),则会遇到问题。修正:

use String::ShellQuote qw( shell_quote );

my $tail_cmd = shell_quote('tail', '-n', '5', '--', $log);
$nexusTime += nexusUploadTime(`$tail_cmd`);

答案 1 :(得分:3)

ikegami pointed out您的错误,但我建议尽可能避免使用外部命令。它们不可移植,调试它们可能是一件痛苦的事情。您可以使用纯Perl代码模拟tail,如下所示:

use strict;
use warnings;

use File::ReadBackwards;

sub tail {
    my ($file, $num_lines) = @_;

    my $bw = File::ReadBackwards->new($file) or die "Can't read '$file': $!";

    my ($lines, $count);
    while (defined(my $line = $bw->readline) && $num_lines > $count++) {
        $lines .= $line;
    }

    $bw->close;

    return $lines;
}

print tail('/usr/share/dict/words', 5);

输出

ZZZ
zZt
Zz
ZZ
zyzzyvas

请注意,如果您传递的文件名包含换行符,则会失败并显示

Can't read 'foo
': No such file or directory at tail.pl line 10.
而不是更神秘的

sh: line 1: -n: command not found

你在反引号中运行tail实用程序。

答案 2 :(得分:0)

这个问题的答案是在目标文件

之前放置选项-n 5