【问题标题】:Tail command used in perl backticksperl 反引号中使用的 tail 命令
【发布时间】:2015-05-29 19:06:03
【问题描述】:

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

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

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

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

sh: line 1: -n: command not found

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

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

有人有什么建议吗?

【问题讨论】:

  • -n 5 放在文件名参数之前。选项应该在文件名之前——在所有经典的 Unix 系统中。 GNU 工具集模糊了该规则,但如果有疑问,文件名之前的选项通常会起作用。
  • 是的,我刚刚意识到这就是问题所在。我发现一篇文章说把选项放在文件名后面。
  • 记得从这里开始忽略那篇文章。
  • @Jonathan Leffler,将$log 放在最后确实可以解决问题,但不是因为您认为的原因。看我的回答。
  • @ikegami:啊; “找不到命令”与“找不到文件”。

标签: perl unix command backticks


【解决方案1】:

$log 有一个多余的尾随换行符,所以你正在执行

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

修复:

chomp($log);

请注意,如果日志$log 包含shell 元字符(例如空格),您将遇到问题。修复:

use String::ShellQuote qw( shell_quote );

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

【讨论】:

    【解决方案2】:

    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 实用程序获得的。

    【讨论】:

    • 如果他正确地逃脱了$log,他就会得到tail: cannot open `foo\n' for reading: No such file or directory。 (实际上是\ 后跟n,而不是换行符。)仅仅因为你掏空并不意味着你不能得到好的错误信息。
    【解决方案3】:

    这个问题的答案是将选项 -n 5 放在目标文件之前

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2011-04-19
      • 2013-06-29
      相关资源
      最近更新 更多