如何设置用php执行的ssh命令的超时?

时间:2012-06-09 00:30:14

标签: php timeout

我使用php通过包装函数通过ssh执行scp命令。这些举措是在本地服务器和远程服务器之间进行的。

我大致知道脚本应该执行多长时间,如果它花费太长时间(由于目标服务器陷入困境或其他网络问题),我想杀死scp进程。当前发生这种情况时,scp进程将完全锁定,直到重新启动目标服务器或从命令行手动终止scp进程。

我可以将某种超时传递给shell_exec(),它会退出它正在进行的工作并继续执行脚本吗?

5 个答案:

答案 0 :(得分:4)

使用UNIX timeout实用程序包装命令。

system('timeout n ../my/aa');
                ^

其中n是一个以秒为单位的整数值。

  

如果命令超时,则退出状态124.否则,退出   具有COMMAND状态。如果未指定信号,请发送TERM   超时时发出信号。 TERM信号会杀死任何没有的进程   阻止或捕获该信号。对于其他过程,可能是必要的   使用KILL(9)信号,因为此信号无法捕获。

答案 1 :(得分:2)

您可以通过执行以下操作,使用phpseclib执行此操作:

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
    exit('Login Failed');
}

$ssh->setTimeout(5);
echo $ssh->read();
//$ssh->write('whatever');
?>

答案 2 :(得分:0)

你可以编写一个shell脚本,你用shell_exec调用,在一段时间后自动调用,然后你直接调用而不是直接调用scp,像这样的脚本会接受参数或硬编码。下面是一个带有2个参数的脚本示例,其中2秒是在终止进程之前等待的秒数。 (睡觉也接受分钟,我们或几天,只需追加m,h或d)

 #!/bin/sh
 scp $1 &
 pid=$!
 sleep $2
 kill $pid

编辑:或使用nickb的解决方案,这甚至更好。 :)

答案 3 :(得分:0)

您可以使用超时的PHP套接字:

$process = proc_open($command,$descriptorspec,$pipes);
stream_set_timeout($pipes[1], 30);
$line=stream_get_contents($pipes[1]);    // read data
while($line)stream_get_contents($pipes[1]);
fclose($pipes[1]);

答案 4 :(得分:0)

或者您可以使用select来等待命令返回。 这是从php手册复制的代码示例 你可以参考proc_open()和stream_select()

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  
   1 => array("pipe", "w"),
   2 => array("file", "/tmp/error-output.txt", "a")
);

$pipes = array();
$process = proc_open('sleep 5 && echo hello', $descriptorspec, $pipes);
$timer = 0;
if (is_resource($process)) {
    while(true) {
        $write = null;
        $except = null;
        $read = array($pipes[1]);
        $ret = stream_select($read, $write, $except, 1);
        if ($ret === false) {
            echo "error";
            break;
        } else if ($ret == 0) {
            echo "waiting for " . ++$timer . "sec" . PHP_EOL;       
        } else {
            echo stream_get_contents($pipes[1]);
            break;
        }
    }
    fclose($pipes[1]);
    $return_value = proc_close($process);
    echo "command returned $return_value\n";
}

?>