【问题标题】:Suppressing output from exec() calls in PHP抑制 PHP 中 exec() 调用的输出
【发布时间】:2010-12-09 01:56:57
【问题描述】:

我在 PHP 中有许多命令行脚本,它们使用exec() 来执行诸如重新启动服务、加载 MySQL 时区文件等任务。虽然 exec() 本身不会向屏幕输出任何内容,但某些命令我正在运行强制输出我似乎无法抑制(即使使用 ob_start()/ob_end_clean())。例如,以下会将时区文件加载到 MySQL 中。我们定期运行以确保 MySQL 时区数据是最新的:

 $command = 'mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql';
 exec($command, $output, $result);

在这个例子中,我希望命令的所有输出都写入 $output,但我仍然会强制显示以下输出:

Warning: Unable to load '/usr/share/zoneinfo/Asia/Riyadh87' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/Asia/Riyadh88' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/Asia/Riyadh89' as time zone. Skipping it.
...

有没有办法抑制这个输出?重定向到 /dev/null 并不理想,因为这会导致 PHP 在不等待命令完成的情况下继续处理。

提前致谢,
〜詹姆斯阿姆斯

【问题讨论】:

  • 对于那些想知道为什么示例代码不起作用的人,这是因为只捕获了stdout。给出的错误正在写入stderr,它不会被捕获而是转储到屏幕上。
  • 我通过 google 来到这个线程,寻找一种在运行 PHP CLI 脚本时抑制所有输出的方法。我的解决方案是将exec() 调用包装在ob_start() 和ob_end_clean() 中。

标签: php


【解决方案1】:

单独重定向 stderr 不应该影响处理发生的位置,只要确保不要添加 &。如果您重定向输出并使其在后台运行,它应该只在后台运行。

编辑:

破解打开cygwin,第一个命令需要重定向stderr,试试这个:

$command = 'mysql_tzinfo_to_sql /usr/share/zoneinfo 2> /dev/null | mysql mysql';
exec($command, $output, $result);

【讨论】:

  • 这并不完全正确。 PHP 手册的意思是,如果你只使用& 而不进行重定向,PHP 仍然会挂起。单独重定向仍然不会导致它在后台运行。
  • 嗯,确实,这似乎更合理。我会更正我的答案
  • 使用 $command = 'mysql_tzinfo_to_sql /usr/share/zoneinfo | 重定向mysql mysql 2> /dev/null';仍然导致相同的输出。但是,像 php mysql_timezones.php 2> /dev/null 这样调用我的脚本会正确地抑制输出。如果不以这种方式调用我的脚本,是否可以获得相同的结果?
  • 试试&> /dev/null。请注意&和>之间没有空格
  • 我只是想通了这一点并来到这里发布我的发现,却发现你打败了我:-P 确实是 mysql_tzinfo_to_sql 输出错误而不是 mysql。感谢所有回复的人!
【解决方案2】:

只需将stderr 重定向到/dev/null

$command = 'mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql 2>/dev/null';

或发送至stdout

$command = 'mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql 2>&1';

【讨论】:

    【解决方案3】:

    重定向到 /dev/null 不会导致 PHP 停止等待命令。添加& 会 这样做,您可能会将两者关联起来,因为最终的& 通常与重定向结合使用。

    回应 Yannick 的(已删除)评论:似乎如果你想在 PHP 中在后台运行某些东西,你必须重定向以及使用&。 这并不意味着仅重定向会导致它在后台运行。

    【讨论】:

    • 根据PHP手册“如果一个程序用这个函数启动,为了让它在后台继续运行,程序的输出必须重定向到一个文件或另一个输出流。否则将导致 PHP 挂起,直到程序执行结束。”虽然看起来你是正确的,但 PHP 需要重定向和后台运算符 &
    • JamesArmes:这正是我回答的第二部分要解释的内容
    【解决方案4】:

    根据http://us3.php.net/manual/en/function.shell-exec.php,您可以将此命令的输出分配给一个变量。

    您不必对变量执行任何操作,这意味着您可以有效地抑制输出。

    希望有帮助!

    【讨论】:

    • 这就是 exec() 调用中的 $output 变量应该做的事情(它通过引用传递)。我曾尝试使用 shell_exec() 并产生相同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多