2

私はphpを使用して、ラッパー関数を介してssh経由でscpコマンドを実行します。移動は、ローカル サーバーとリモート サーバーの間で行われます。

スクリプトの実行時間を大まかに知っていますが、時間がかかりすぎる場合は scp プロセスを強制終了したいと考えています (宛先サーバーが停止したり、その他のネットワークの問題が原因で)。これが現在発生すると、宛先サーバーが再起動されるか、scp プロセスがコマンド ラインから手動で強制終了されるまで、scp プロセスは完全にロックされます。

ある種のタイムアウトを shell_exec() に渡して、実行中の作業を終了し、スクリプトの実行を続行することはできますか?

4

5 に答える 5

5

timeoutコマンドを UNIXユーティリティでラップします。

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

n単位の整数値です。

コマンドがタイムアウトした場合は、ステータス 124 で終了します。それ以外の場合は、COMMAND のステータスで終了します。シグナルが指定されていない場合、タイムアウト時に TERM シグナルを送信します。TERM シグナルは、そのシグナルをブロックまたはキャッチしないプロセスを強制終了します。他のプロセスでは、このシグナルをキャッチできないため、KILL (9) シグナルを使用する必要がある場合があります。

于 2012-06-09T00:43:57.690 に答える
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');
?>
于 2012-06-13T21:12:11.333 に答える
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]);
于 2012-06-09T00:47:27.137 に答える
0

一定時間後に自動強制終了する shell_exec で呼び出すシェル スクリプトを作成し、それを scp の代わりに直接呼び出すことができます。このようなスクリプトは、引数を取るかハードコーディングします。2 つの引数を取るスクリプトの例を次に示します。2 秒は、プロセスを強制終了する前に待機する秒数です。(sleep は、分、ours、または days も受け入れます。m、h、または d を追加するだけです)

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

編集:またはnickbのソリューションを使用すると、さらに優れています。:)

于 2012-06-09T00:42:58.120 に答える
0

または、select を使用して、コマンドが戻るのを待つことができます。proc_open() および stream_select() を参照できる PHP マニュアルからコピーしたコードの例を次に示します。

<?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";
}

?>
于 2012-06-09T01:58:04.587 に答える