【问题标题】:How do i fix the error 'The command line is too long' if i want to have the output from a command?如果我想获得命令的输出,如何修复错误“命令行太长”?
【发布时间】:2019-05-03 22:45:11
【问题描述】:

我有一个带有很长命令的 perl 代码,我想将输出打印到日志文件。它看起来像这样:

system ( "$cmd  | tee -a $log_file" );

当我运行 Perl 脚本时,系统调用抛出“命令行太长”。

如果我在没有管道的情况下运行系统调用,它可以工作。

所以我的问题是:

  1. 管道是否有字符限制?
  2. 我该如何解决这个问题?

一些附加信息:

$cmd 命令的长度为 8532。我使用的是 Perl 版本 5.003_07(是的,我知道它很旧。我的公司是所有者。

【问题讨论】:

  • 嗨,什么操作系统?您是否尝试过在命令提示符下运行命令?当然,无论有无管道。
  • 5.003_07 于 1996 年 10 月 10 日发布!!!当时的普通人从未听说过互联网。

标签: perl pipeline


【解决方案1】:

这是一个非常古老的 Perl 版本。我使用的第一个是 90 年代中期的 5.004。诚然,事情可能已经改变,但我认为system() 文档中的以下引用仍然相关。

如果只有一个标量参数,则检查参数是否有 shell 元字符,如果有,则将整个参数传递给系统的命令 shell 进行解析(在 Unix 上是“/bin/sh -c”平台,但在其他平台上有所不同)。如果参数中没有shell元字符,则将其拆分为单词并直接传递给“execvp”,这样效率更高。

您似乎遇到了这两种情况之间的差异,并且(外部)shell 程序在您添加管道时施加了长度限制。

您可以通过暂时将 STDOUT 重新打开为“| tee -a $log_file”,然后执行 system($cmd) 来解决此问题。我不敢告诉你在如此古老的 Perl 版本下究竟如何做到这一点(特别是如果你想在之后恢复旧的 STDOUT),因为随着时间的推移,这肯定会发生变化。您需要查阅手头的文档。

一种可能性是fork(),然后在子进程中open STDOUT, "| tee -a $log_file"exec($cmd),在父进程中wait() 完成所有这些,记住有不止一个子进程因为你打开了一个管道。

【讨论】:

  • 想一想,我不确定在 STDOUT 本身是管道的情况下,“tee”会产生什么影响。宇宙可能会爆炸。
  • 嗯,我刚刚试了一下,达到了想要的效果,宇宙还在。 perl -we 'open STDOUT, "|tee /tmp/foo" or die "$!\n";系统(“ls”)'
  • 很高兴我们所有人都承担了风险。
  • 如果我要做一些可能会导致宇宙爆炸的事情,我认为获得宽恕比获得许可更容易。
  • @TFBW 它适用于您提到的 open ( STDOUT... 和 system($cmd) 。非常感谢。它可以标记为已解决。
猜你喜欢
  • 1970-01-01
  • 2013-12-06
  • 2019-05-08
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多