PHP 脚本不会死于 control +c
PHP script wont die on control +c
我有一个 PHP 脚本,它使用 exec 在 Linux 中启动一些命令。这是一个简单的 wget,将在五分钟后结束。我面临的问题是,如果我执行 Control + c,因为脚本是 运行 它不会死,直到我杀死 wget 的实际 PID。我尝试使用 pcntl_signal 以及 exec/system/shell_exec 等,其中 none 有效。我使用的代码是:
<?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');
?>
首先,您必须声明 ticks
directive to make it work in PHP 4.3.0 and newer (see the manual page for pcntl_signal
).
然后你必须注册信号和接收到信号时调用的回调函数。在您的情况下,您需要在按下 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
这是因为终端输入中断键产生的信号SIGINT
只发送给终端的前台进程组,而timeout
segregates itself and the given command from the foreground process group by executing <a href="https://linux.die.net/man/2/setpgid" rel="nofollow noreferrer">setpgid</a>(0, 0)
.
现在,由于 SIGINT
没有发送到 timeout
命令,前台进程必须处理该信号,然后终止 timeout
命令。正如我们从其他答案的失败中了解到的那样,PHP 不太适合这种信号处理,但我们可以为此使用一个小包装脚本(我们称之为 timeout.sh
):
time=; shift
timeout $time "$@"&
trap "kill $!" INT
wait $!
<?PHP
system('timeout.sh 300 wget -c --tries=0 --read-timeout=200 -O /tmp/ll.mp3 …');
?>
我有一个 PHP 脚本,它使用 exec 在 Linux 中启动一些命令。这是一个简单的 wget,将在五分钟后结束。我面临的问题是,如果我执行 Control + c,因为脚本是 运行 它不会死,直到我杀死 wget 的实际 PID。我尝试使用 pcntl_signal 以及 exec/system/shell_exec 等,其中 none 有效。我使用的代码是:
<?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');
?>
首先,您必须声明 ticks
directive to make it work in PHP 4.3.0 and newer (see the manual page for pcntl_signal
).
然后你必须注册信号和接收到信号时调用的回调函数。在您的情况下,您需要在按下 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
这是因为终端输入中断键产生的信号SIGINT
只发送给终端的前台进程组,而timeout
segregates itself and the given command from the foreground process group by executing <a href="https://linux.die.net/man/2/setpgid" rel="nofollow noreferrer">setpgid</a>(0, 0)
.
现在,由于 SIGINT
没有发送到 timeout
命令,前台进程必须处理该信号,然后终止 timeout
命令。正如我们从其他答案的失败中了解到的那样,PHP 不太适合这种信号处理,但我们可以为此使用一个小包装脚本(我们称之为 timeout.sh
):
time=; shift
timeout $time "$@"&
trap "kill $!" INT
wait $!
<?PHP
system('timeout.sh 300 wget -c --tries=0 --read-timeout=200 -O /tmp/ll.mp3 …');
?>