微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当使用Php exec()执行bash脚本时,为什么Php等待不知名的后台作业完成?

我可以使用一些帮助来了解为什么会这样.我正在从命令行运行PHP脚本,该脚本通过exec()启动bash脚本.在bash脚本中,我正在后台创建一个进程(例如sleep 5; echo“ Hello”&).我期望PHP启动bash脚本,然后在完成后继续前进.但是,PHP似乎正在等待bash脚本启动的后台进程完成,然后再执行其余脚本

为了演示,我将在linux shell环境中使用以下3个示例脚本:

runstuff.PHP

<?PHP

echo "PHP running stuff.sh..." . PHP_EOL;
exec('./stuff.sh &');
echo "PHP done running stuff.sh..." . PHP_EOL;

小编

#!/bin/bash

echo "stuff.sh running background process..."
# This can be a script or any process placed in the background
./test-script.sh &
echo "stuff.sh done"

测试脚本

#!/bin/bash

echo "test-script.sh waiting 5 seconds..."
sleep 5
echo "test-script.sh COMPLETE"

现在,运行PHP runstuff.PHP(从命令行)将“挂起”,直到test-script.sh完成,然后PHP遍历脚本的其余部分.但是,直接运行./stuff.sh将立即返回命令行提示符,并在5秒钟后显示输出.

查看运行runstuff.PHP时的进程列表,我可以看到test-script.sh既不是runstuff.PHP也不是stuff的子级,stuff.sh不再存在:

 5873 pts/3    Ss     0:01  \_ bash
27389 pts/3    S+     0:00  |   \_ PHP runstuff.PHP
27390 pts/3    Z+     0:00  |       \_ [stuff.sh] <defunct>


27392 pts/3    S+     0:00 /bin/bash ./stuff.sh
27393 pts/3    S+     0:00  \_ sleep 5

直接运行./stuff.sh时,stuff.sh看起来不错.

27963 pts/3    S      0:00 /bin/bash ./stuff.sh
27965 pts/3    S      0:00  \_ sleep 5

所以我的问题是这样的:为什么当通过PHP exec()执行stuff.sh时会挂起,而直接运行脚本时却没有挂起?即使它与stuff.sh分离,PHP是否仍会以某种方式将test-script.sh识别为子进程?

而且,似乎将stuff.sh修改为使用&>. / dev / null&而不只是&似乎按预期工作.

修改的stuff.sh

#!/bin/bash

echo "stuff.sh running background process..."
./test-script.sh &> /dev/null &
echo "stuff.sh done"

那么,为什么将输出重定向到/ dev / null会产生预期的结果?

解决方法:

PHP exec(..)打开命令的管道,并从中读取直到关闭,然后将数据作为字符串返回(不使用).

在所有编写者都将其关闭之前,管道不会关闭,因此在以stdout打开管道的任何后台进程都会使其保持打开状态.因此,执行人员会继续等待他们,以为可能会有更多的输出.这也是一件好事:五秒钟后,它读取一条“ test-script.sh COMPLETE”消息,否则该消息将消失.

当您将stdout重定向到/ dev / null而不是后台进程时,它将不会保持管道打开,因此exec会立即返回,因为可能再也没有输出了.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐