我可以使用一些帮助来了解为什么会这样.我正在从命令行运行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 举报,一经查实,本站将立刻删除。