我正在尝试使用PHP触发一个永远不会停止运行的bash脚本。这不仅是命令需要运行并且我不需要等待输出,还需要在PHP完成后继续运行。这在其他时候也奏效了(并且已经提出了问题),区别似乎是我的bash脚本在关闭时有一个陷阱。
这是我的bash脚本:
#!/bin/bash
set -e
WAIT=5
FILE_LOCK="$1"
echo "Daemon started (PID $$)..."
echo "$$" > "$FILE_LOCK"
trap cleanup 0 1 2 3 6 15
cleanup()
{
echo "Caught signal..."
rm -rf "$FILE_LOCK"
exit 1
}
while true; do
# do things
sleep "$WAIT"
done
这是我的PHP:
$command = '/path/to/script.sh /tmp/script.lock >> /tmp/script.log 2>&1 &';
$lastLine = exec($command, $output, $returnVal);
我看到脚本正在运行,已创建锁定文件,然后退出,然后陷阱删除了锁定文件。在我的/tmp/script.log
中,看到:
Daemon started (PID 55963)...
Caught signal...
奇怪的是,这仅在通过Apache运行PHP时发生。从命令行,它可以按预期运行。
正在捕获的陷阱上的信号为0
。
我尝试将命令包装在bash环境中,例如$command = '/bin/bash -c "' . addslashes($command) . '"';
,也尝试将nohup
添加到开头。似乎没有任何作用。这对一个永无止境的脚本有可能吗?
答案 0 :(得分:0)
通过@lxg找到了问题。
我的# do things
命令给出了错误,这导致脚本退出。由于某些原因,他们被压制了。
从bash脚本的开头删除set -e
时,我开始看到输出到日志文件的错误。不知道为什么他们以前没有出现过。
问题出在我的bash循环中,它正在运行PHP命令。尽管我的bash用户和Apache用户相同,但由于某些原因,他们有不同的$PATH
。这意味着当在命令行上运行时,我使用的是PHP7二进制文件,但是当Apache触发bash命令时,它使用的是PHP5二进制文件(即使Apache本身已配置为使用PHP7)。因此,应用程序出错了,这就是导致脚本死亡的原因。
解决方案是在我的bash循环中显式设置PHP二进制路径。
我在做这个
BIN_PHP=$(which php)
但是在真实的命令行上,它将返回一个值(/path/to/php7/bin/php
)与Apache(/path/to/php5/bin/php
)启动的命令行相比。尽管Apache与我的命令行用户相同,但并未加载指定我正确的PHP路径的~/.bashrc
。