如果我想获得命令的输出,如何修复错误 'The command line is too long'?

How do i fix the error 'The command line is too long' if i want to have the output from a command?

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

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

当我 运行 Perl 脚本时,系统调用抛出 "The command line is too long"。

如果我 运行 没有管道的系统调用,它会工作。

所以我的问题是:

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

一些附加信息:

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

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

If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to "execvp", which is more efficient.

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

您可以临时重新打开 STDOUT 作为“| tee -a $log_file”,然后只执行 system($cmd) 来解决这个问题。我不敢尝试告诉您在如此古老的 Perl 版本下如何准确地做到这一点(特别是如果您想事后恢复旧的 STDOUT),因为这肯定会随着时间的推移而改变。您需要查阅手头的文档。

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