简体   繁体   English

PHP脚本不会在Control + C上死亡

[英]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.

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