首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >php在执行外部sh脚本时冻结

php在执行外部sh脚本时冻结
EN

Stack Overflow用户
提问于 2015-02-19 17:05:52
回答 2查看 791关注 0票数 0

我将尝试用时间线的历史来解释我的问题:

我尝试从php运行几个外部脚本,并再次使用ajax调用将退出代码返回到服务器。一个单独的呼叫应该启动或停止该机器上的服务。在这台开发机器上工作得很好。

  • OS : raspbian
  • Webserver服务器: NginX 1.2.1
  • Php : 5.4.3.6

然而,我已经将代码导出到一台更大的机器上,拥有更多的功能,一切看起来都很好,但有一件事:一个调用就会导致php冻结,再也不会回来了。通过详细的检查,我发现,调用创建了一个僵尸进程,我无法终止(即使使用sudo)。

  • 操作系统: Ubuntu
  • Webserver服务器: NginX 1.6.2
  • Php : 5.5.9

唯一的解决方案似乎是停止php proc,而不是重新启动它。那么,只要我再次尝试调用该脚本,一切似乎都会恢复正常。

调用php行

代码语言:javascript
复制
exec("sudo ".$script, $output, $return_var);

(所有变量都是普通的“字符串”,没有特殊字符)

启动脚本

代码语言:javascript
复制
#!/bin/sh
service radicale start 2>&1

顺便说一下,服务开始了,但是每次web服务器冻结时,我不得不手动重新启动php,但这是不可接受的(即使对于web服务器)。但只适用于单一的脚本,也只适用于带有庄严命令的服务(激进)(开始)。

在Google中搜索使我意识到,php命令exec()和之间存在冲突。

链接:

https://bugs.php.net/bug.php?id=44942

https://bugs.php.net/bug.php?id=44994

他们的结论是,这个bug可以用这样的结构来解决:

代码语言:javascript
复制
...
session_write_close();
exec("sudo ".$script, $output, $return_var);
session_start();
...

但在我看来,这不是调试,而是一种无助的解决办法,因为你失去了让用户知道他的行为已经完全发挥作用的功能,但更多的是让他相信已经发生了错误。更令人困惑的是,它完全在Raspberry Pi A上运行,而不是在64位计算机上运行,它的CPU和8GB内存要大得多。

那么,在任何地方是否都有真正的解决方案,或者这是解决该问题的唯一方法?我读过一篇关于php与exec/shell_exec有一些问题以及对返回值的识别的文章。怎么会丢失呢?有人在猜吗?

因为我读了那么长一段糟糕的英语,但我不是以英语为母语的人,在我的课上听学生的话也不太好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-20 16:11:19

这不是一个真正的解决方案,但它是一个比没有更好的解决方案。

调用bash脚本

代码语言:javascript
复制
<?php
...
exec("sudo ".$script, $output, $return_var);
...
?>

只有在这种特殊情况下,才会以僵尸线程结束。当php等待结果时,它仍然保持行,不会放弃,也不会为其其余线程仍然存在超时。因此,对php服务器的每一个其他请求仍然处于队列中,并且永远不会被处理。这对于一些长期存在或工作的线程来说可能是可以的,但我的请求在一些ms中完成了。

我没有找到原因。就我所能做的调试而言,我不是触发的激进进程错误,因为这给了我任何时间的清洁和勇敢的0作为回报。看起来,php进程无法从它得到一个返回线,所以它仍然在等待和等待。

没有时间了,我把故障脚本从

代码语言:javascript
复制
#!/bin/sh
service radicale start 2>&1

代码语言:javascript
复制
#!/bin/sh
service radicale start > /dev/null 2>&1 &

..。因此,向涅槃发送每条返回线路的信号,并断开所有子程序。目前,服务器并没有自行挂起并按需要工作。但是我仍然觉得这可能是php中的一个主要bug,希望有一天有人会打败这个bug。

票数 -1
EN

Stack Overflow用户

发布于 2015-02-19 17:40:40

很可能是因为新机器没有按照Raspberry PI的设置方式-

您需要在shell中做一些事情,然后才能在更大的机器上工作:

1)。允许php使用sudo。

sudo usermod -G sudo -a your-php-user

请注意,要获取your-php-user的用户名,只需运行以下脚本:

<?php echo get_current_user(); ?> -或者选择:<?php echo exec('whoami'); ?> -

2)。允许该用户使用没有密码的sudo

sudo visudo -此命令将使用故障安全打开/etc/sudoers,以防止您处理任何问题。

将这一行添加到最后面:

your-php-user ALL=(ALL) NOPASSWD: /path/to/your/script,/path/to/other/script

您可以根据需要将任意多的脚本放在那里,用逗号分隔。现在,您的脚本应该工作得很好。

同样,请注意,您需要将your-php-user更改为任何您的php用户。

希望这能有所帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28612442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档