我使用php通过包装函数通过ssh执行scp命令。这些举措是在本地服务器和远程服务器之间进行的。
我大致知道脚本应该执行多长时间,如果它花费太长时间(由于目标服务器陷入困境或其他网络问题),我想杀死scp进程。当前发生这种情况时,scp进程将完全锁定,直到重新启动目标服务器或从命令行手动终止scp进程。
我可以将某种超时传递给shell_exec(),它会退出它正在进行的工作并继续执行脚本吗?
答案 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";
}
?>