[英]PHP script wont die on control +c
I have a PHP script that uses exec to launch some commands in Linux. 我有一个使用exec在Linux中启动某些命令的PHP脚本。 It's a simple wget that is set to die after five minutes hour.
这是一个简单的wget,它将在五分钟后消失。 The issue I am facing is if I do Control + c as the script is running it wont die till I kill the actual PID of the wget.
我面临的问题是,如果我在脚本运行时执行Control + c,则直到我杀死wget的实际PID之前,它都不会消失。 I tried using pcntl_signal as well as using exec/system/shell_exec etc. and none of them worked.
我尝试使用pcntl_signal以及使用exec / system / shell_exec等,但没有一个起作用。 The code I am using is:
我使用的代码是:
<?PHP
system('/usr/bin/timeout 300 wget -c --tries=0 --read-timeout=200 -O /tmp/ll.mp3 http://15323.live.streamtheworld.com:80/WABCAM_SC');
?>
First of all, you have to declare the ticks
directive to make it work in PHP 4.3.0 and newer (see the manual page for pcntl_signal
). 首先,您必须声明
ticks
指令以使其在PHP 4.3.0和更高版本中起作用(请参见手册页上的pcntl_signal
)。
Then you have to register the signal and the callback function which is called when the signal is received. 然后,您必须注册信号和接收信号时调用的回调函数。 In your case, you want the signal
SIGINT
which is generated when CTRL + C pressed. 在您的情况下,您需要按CTRL + C时生成的信号
SIGINT
。
declare(ticks = 1);
// callback function called when signal is received
function shutdown($signal)
{
echo 'Interrupted using CTRL + C';
// you probably don't need this condition, just exit should be enough
if (($signal === SIGINT)) {
exit;
}
}
// register the callback function for the specific signal
// SIGINT in this case is generated when you press CTRL + C
pcntl_signal(SIGINT, 'shutdown');
if I do Control + c as the script is running it wont die
如果我在脚本运行时执行Control + c,它将不会死亡
This is because the signal SIGINT
generated from the terminal by typing the interrupt key is sent only to the foreground process group for the terminal, and timeout
segregates itself and the given command from the foreground process group by executing setpgid (0, 0)
. 这是因为通过键入中断键从终端生成的信号
SIGINT
仅发送到终端的前台进程组,并且timeout
通过执行setpgid (0, 0)
隔离自身和前台进程组中的给定命令。
Now, since the SIGINT
is not sent to the timeout
command, a foreground process would have to handle the signal and thereupon kill the timeout
command. 现在,由于未将
SIGINT
发送给timeout
命令,因此前台进程将必须处理该信号,并随后终止timeout
命令。 As we learn from the failure of an other answer, PHP is not well suited for such signal handling, but we can use a little wrapper script (let's call it timeout.sh
) for this: 正如我们从另一个答案的失败中学到的那样,PHP不太适合这种信号处理,但是我们可以为此使用一些包装器脚本(将其称为
timeout.sh
):
time=$1; shift
timeout $time "$@"&
trap "kill $!" INT
wait $!
<?PHP
system('timeout.sh 300 wget -c --tries=0 --read-timeout=200 -O /tmp/ll.mp3 …');
?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.