【问题标题】:calling find with backticks from perl - find: write error: Broken pipe从 perl 中使用反引号调用 find - 查找:写入错误:管道损坏
【发布时间】:2011-09-30 08:14:41
【问题描述】:

我从这样的 perl 脚本调用 find:

我的 $one_file = `find $search_dir -name "\*.$refinfilebase.search" -print |头-n 1`;

如果我从 shell 执行它,我不会收到任何错误。此外,它将正确的值返回给 $one_file,但我在提示符下得到了这个:

发现:写入错误:断管

为什么会这样?我怎样才能摆脱这个 find: write error: Broken pipe 消息?

【问题讨论】:

  • 尝试从shell执行,是否出现同样的错误?
  • 已编辑:如果我从 shell 执行它,我不会收到任何错误。此外,当从 Perl 调用时它返回正确的值,但我总是得到错误提示。
  • 这可能会有所帮助:How to detect whether “find” found any matches? 请注意可能使用-quit 而不是head -n 1 并提到head 缓冲区已满。

标签: perl unix scripting find


【解决方案1】:

这个“错误”是完全正常的,是意料之中的。

  • 您正在运行一个 find 命令,该命令会打印出(可能)多行输出。
  • 您将其输入到head,它会在收到一行输入后退出。
  • find 命令尝试将其剩余的行写入一个不再有人监听的管道(head 已死)。
  • find 会抛出错误。

如果您想摆脱错误,只需执行以下操作:

my $file = `find .... 2>/dev/null | head -n 1`;

这将阻止完全可预测的错误 find 到达您的终端(因为反引号和管道都没有进入 head touch stderr,这是打印错误的地方)。

【讨论】:

  • 虽然我的回答回答了您的实际问题,但@TLP 的回答为您指明了正确的方向。如果您可以直接在脚本中执行,那么肯定没有理由产生三个额外的进程(shell、find、head)。您也不太容易受到黑客攻击,因为您不会运行一个将您的变量之一放入其中的 shell(例如 let $refinfilebase = '"; rm -rf /; "echo '
【解决方案2】:

你为什么在反引号中使用findhead,而有perl 方法来处理它?即:

我只建议在您完全确定自己在做什么时使用反引号,而在我看来您不是。哎呀,您只需执行以下操作即可使当前的尝试生效:

my @files = `find $search_dir -name "\*.$refinfilebase.search" -print`
my $one_file = $files[0];

【讨论】:

  • 什么方法可以用于最旧的 perl 版本?钻石算子?
  • @avi 为此,您需要提出一个新问题。我自己也喜欢 opendir。
【解决方案3】:

你可以试试这个(虽然我没有设法使用你发布的代码重现你的错误消息,所以也许我的这个无错误版本也可能会给你一个错误消息......):

my $file = `find $search_dir -name "\*.ssf" -print -exec head -n 1 {} \\;`;

这是我从测试运行中得到的一些示例输出:

./tmp1.ssf
HEADER    PROTEIN                                 21-FEB-11     1PDB

HTH

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2011-05-05
    • 2016-10-27
    • 1970-01-01
    • 2011-07-13
    • 2016-10-05
    相关资源
    最近更新 更多