繁体   English   中英

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

[英]php freezes when executing an external sh script

我会尝试在时间线历史中解释我的问题:

我试图从php运行几个外部脚本,并再次使用ajax调用将退出代码返回给服务器。 单个调用应该启动或停止该计算机上的服务。 这在开发的机器上运行良好。

  • 操作系统:raspbian Os
  • 网络服务器:NginX 1.2.1
  • Php:5.4.3.6

然而,我已经将代码导出到更大功率的更大的机器上,一切似乎都运行良好但有一点:单个调用导致php-fpm冻结,永远不会回来。 通过详细的检查,我发现,调用创建了一个僵尸进程,我无法终止(即使使用sudo)。

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

唯一的解决方案似乎是停止php-fpm proc而不是重新启动它。 然后一切似乎再次正常工作,只要我再次尝试调用该脚本。

调用php行

exec("sudo ".$script, $output, $return_var);

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

启动脚本

#!/bin/sh
service radicale start 2>&1

顺便说一下,服务开始,但每次网络服务器冻结,我不得​​不手动重启PHP,但这是不可接受的(即使对于Web服务器)。 但只适用于那个单一的脚本,只有那个服务(radicale)才能使用那个庄严的命令(开始)。

在Google中搜索让我发现php命令exec()session_start()之间存在冲突。

链接:

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

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

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

...
session_write_close();
exec("sudo ".$script, $output, $return_var);
session_start();
...

但是,对于我来说,这不是调试,而是更多无助的解决方法,因为你失去了让用户知道的功能,他的行为已经完全发挥作用,但更让他相信发生了错误。 令人困惑的是,它完全在Raspberry Pi A上运行,而不是在具有更大CPU和8 GB RAM的64位机器上运行。

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

THX用于阅读那个长得太糟糕的英语,但我不是母语,而且在我的课程中没有很好听的学生。

可能的情况是,新机器的设置方式与Raspberry PI的设置方式不同 -

你需要在shell中做一些事情,然后才能在更大的机器上运行:

1)。 允许php使用sudo。

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

请注意,要获取your-php-user ,您只需运行一个脚本:

<?php echo get_current_user(); ?> <?php echo get_current_user(); ?> - 或者: <?php echo exec('whoami'); ?> <?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用户。

希望这可以帮助!

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

用。调用bash脚本

<?php
...
exec("sudo ".$script, $output, $return_var);
...
?>

仅在僵尸线程中的这种特殊情况下结束。 由于php-fpm等待结果的预期,它仍然保持着这条线,不会放弃,也不会超时剩下的线程仍然存在。 所以对php服务器的每个其他请求仍然在队列中,永远不会被处理。 对于一些长期生活或工作线程来说,这可能没问题,但我的请求是在某些[ms]中完成的。

我没有找到原因。 至于我可以做的调试,我不是触发的Radicale过程故障,因为这给了一个任何时间干净和勇敢0作为回报。 似乎php进程无法从它获得返回线,因此它仍然等待并等待。

没时间了,我改变了故障脚本

#!/bin/sh
service radicale start 2>&1

#!/bin/sh
service radicale start > /dev/null 2>&1 &

...所以将每个返回线路发送到必杀技并断开所有子程序。 目前,服务器没有自行挂起并按预期工作。 但感觉这可能是PHP中的一个主要错误仍然留在我的脑后,希望,有一天 - 有人可能会打败那个bug。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM