【问题标题】:Run mysqldump via php exec(), pipe to gzip, return mysqldump stderr通过 php exec() 运行 mysqldump,管道到 gzip,返回 mysqldump stderr
【发布时间】:2012-12-16 16:06:00
【问题描述】:

解决方案见底部

我正在运行 mysqldump 作为通过 cron 作业调用的 php 脚本的一部分。

是否可以从 mysqldump 命令返回stderr,或者将其分配给可以直接读取的变量?或者是否可以将stderr 分配给exec() 命令的output 或return_var?

使用的基本命令:

$dump_cmd = 'mysqldump -u username -pPassword db_name --tables db_table --where="field1 = abc" | gzip -c > dumpfile.sql.gz';

exec( $dump_cmd, $dump_cmd_output, $dump_cmd_return_var );

来自exec() 的output 和return_var 没有帮助:

$dump_cmd_output 为空,因为输出通过管道传输到 gzip。

$dump_cmd_return_var 显示 gzip 的返回状态。


我知道有其他方法可以查看 mysqldump 运行时是否出现任何错误:

我可以直接进行转储而不使用 gzip,检查 $dump_cmd_return_var 的返回状态,然后将 gzip 作为附加命令运行。

$dump_cmd = 'mysqldump -u username -pPassword db_name --tables db_table --where="field1 = abc" --result-file="dumpfile.sql"';

$zip_cmd = 'gzip dumpfile.sql';

exec( $dump_cmd, $dump_cmd_output, $dump_cmd_return_var );

if($dump_cmd_return_var == 0) {
  exec( $zip_cmd, $zip_cmd_output, $zip_cmd_return_var );
}

我可以使用 mysqldump 的--log-error=dump_errors.txt 选项将stderr 从 mysqldump 发送到文件:

$dump_cmd = 'mysqldump -u username -pPassword db_name --tables db_table --where="field1 = abc" --log-error=dump_errors.txt | gzip -c > dumpfile.sql.gz';

或者通过将stderr 发送到管道2> dump_errors.txt 之前的文件:

$dump_cmd = 'mysqldump -u username -pPassword db_name --tables db_table --where="field1 = abc" 2> dump_errors.txt | gzip -c > dumpfile.sql.gz';

或者我可以尝试使用proc_open()。虽然我预计我会遇到与 exec() 相同的问题,但已执行命令 (return_var) 的返回状态显示了 gzip 返回的状态。


如果直接返回任何错误或将错误发送到可从脚本访问的变量会更简洁(不太复杂),所以我很好奇这是否可能。


解决方案:

@user1281385 有一个很好的解决方案。为了更好的理解,我搜索了一下:
“bash PIPESTATUS[0]”

一个结果使用了这个确切的场景(mysqldump 管道到 gzip)。这是任何想要了解更多信息的人的链接:
Bash - How to check the exit status of pipe command

这是我的使用方法:

$dump_cmd = 'mysqldump -u username -pPassword db_name --tables db_table --where="field1 = abc" | gzip -c > dumpfile.sql.gz';

system("bash -c '".$dump_cmd." ; exit \${PIPESTATUS[0]}'", $dump_cmd_return);

if($dump_cmd_return == 0) {
  Do some other stuff;
}

基本上,mysqldump命令是第一个执行的,所以它的返回值存储为PIPESTATUS数组的第一个值(key [0])。

【问题讨论】:

  • 完全选择proc_open 解决方案,因为它似乎可以为您提供您所需要的——直接访问stderr。有点。我实际上不确定它对管道命令有何反应。我希望你会得到 gzip 标准错误,而不是 mysqldump 标准错误...
  • 我应该说或“尝试”使用proc_open(),我想我会遇到与来自 exec 的 return_var 返回 gzip 状态时相同的问题。
  • 是的,几乎可以肯定。您是否有足够的磁盘空间和分配的时间来将 gzip 作为单独的命令执行?
  • 是的,我只是想看看是否有更清洁的方法。

标签: php error-handling exec mysqldump


【解决方案1】:

proc_open 是我唯一使用的方式

PHP StdErr after Exec()

类似的问题

如果它只是你的标准错误,你可以将标准输出重定向到无处和标准错误到标准输出

或使用 PIPESTAUS

system("bash -c 'your_command ; exit \${PIPESTATUS[0]}'", $return);

需要通过与 sh 兼容的东西来调用管道状态。在这种情况下,bash。

bash -c 通过 bash 运行命令,PIPESTATUS 将显示管道每个部分的数组。

【讨论】:

  • 感谢您的回复,您指出的问题很好地概述了使用 proc_open,但它不适合我想要完成的工作。
  • 如何使用 pipestatus 和 bash -c ? system("bash -c 'your_command ; exit \${PIPESTATUS[0]}'", $return);
  • 太棒了,它完全符合我的要求。请把它放在你的答案中,这样我就可以接受它,其他任何正在寻找的人都会看到它。我在 bash PIPESTATUS 上进行了搜索,所以我可以理解它是如何工作的,并找到了一篇专门针对使用 mysqldump 管道传输到 gzip 的帖子,太糟糕了,我不知道从什么开始。我会将链接放在我的问题中,但如果你在回答中解释它,人们就不必费心点击链接了。
猜你喜欢
  • 1970-01-01
  • 2012-07-25
  • 2018-02-19
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2015-10-20
  • 2012-03-19
  • 1970-01-01
相关资源
最近更新 更多