0

Linux ローカル コンピューターを使用しており、非常に大きなファイル構造を定期的にバックアップ/ミラーリングする必要があります。SFTP にしかアクセスできません。

私は簡単なワンクリックソリューションを求めていました。私は当初、BASH で小さなスクリプトを作成しようとしましたが、これまで使用したことがなく、構文に慣れていないため、PHP に頼りました。(PHPがこの種の作業用に設計されていないことは理解していますが、私は時間的規模が厳しく、BASH atmに入る時間がありません)

<?php
//init
parse_str(implode('&', array_slice($argv, 1)), $_GET);
$error = array();

$lPrefix         = '/home/hozza/Sites/';
$archiveLocation = '/home/hozza/Backups/';

$lDir = isset($_GET['l']) ? $_GET['l'] : $error[] = 'Local Directory Required';
$rDir = isset($_GET['r']) ? $_GET['r'] : $error[] = 'Remote Directory Required';
$bookmark = isset($_GET['b']) ? $_GET['b'] : $error[] = 'lftp Bookmark Required';

//Check for args
if(count($error) == 0) {
    $archiveName = end(explode('/', $lDir)) . '_' . date('Y-m-d_H-i');

    //Validate local dir
    if(is_dir($lPrefix . $lDir)) {

        //preserve Sublime Text 2 config SFTP files
        $ST2_SFTP_conf = false;
        if(file_exists($lPrefix . $lDir . '/sftp-config.json')) {
            $ST2_SFTP_conf = file_get_contents($lPrefix . $lDir . '/sftp-config.json');
            unlink($lPrefix . $lDir . '/sftp-config.json');
        }

        //Start mirror
        $lftOutput = explode("\n", shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark));

        //Tar regardless of lftp error or success
        $tarOutput = shell_exec('cd ' . $lPrefix . ' && tar -czf ' . $archiveLocation . $archiveName . '.tar.gz ' . $lDir);

        //Output completion or errors
        shell_exec('notify-send -i gnome-network-properties -t 0 "Mirror & Archive Complete" "' . $archiveName . '\n\n' . implode('\n', $lftOutput) . $tarOutput . '"');

        //put back ST2 SFTP conf
        if($ST2_SFTP_conf != false) file_put_contents($lPrefix . $lDir . '/sftp-config.json', $ST2_SFTP_conf);

        exit;
    }
    else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . $lDir . ' \n Does not exist! D:"');
}
else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . implode('\n', $error) . '"');
?>

次のようなショートカットを介して多くのサイトで実行できます...

terminator -T "Mirror & Archive" -e "php ~/Programs/mirror.php l=local-dir_path r=./ b=lftp-bookmark-name"

LFTP ブックマークにパスワードがない場合 (プレーン テキストで保存されているため、存在しないはずです)、ターミナルはパスワードの入力を求めます。スクリプトが実行された後、ファイル/フォルダー/速度などに関する情報を含む適切な通知が表示されます。

ただし、スクリプトが端末で実行されている場合、「入力パスワード」ビットのみが端末に出力されます。すべての出力を端末に表示したいと思います(通常、現在作業中のファイル/フォルダーなどを表示します)。

誰もそれを行う方法を知っていますか?

4

2 に答える 2

3

IIRC 端末にパスワード プロンプトの出力が表示される理由は、それが を使用しているためですstderr。「リアルタイム」の進行状況を表示するコマンドにリダイレクトstdoutしてみてください。stderrこれをshell_exec()コマンドの最後に追加します。1>&2

すなわち:

shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark . ' 1>&2')

shell_execただし、これにより、ログの目的でから何かが返されなくなります。私が提案するのは次のようなものです:

$log_stem = '/tmp/' . time() . '_';  // ie: /tmp/1357581737_
$lfOutfile = $log_stem . 'lftp.log';
$tarOutfile = $log_stem . 'tar.log';

shell_exec('lftp -blah | tee ' . $lfOutfile ' 1>&2' );
shell_exec('tar -blah | tee ' . $tarOutfile ' 1>&2' );

$lfOut = file_get_contents($lfOutfile);
$tarOut = file_get_contetns(tarOutfile);

// remove tmp files
unlink($lfOutfile);
unlink($tarOutfile);

出力をstderrにリダイレクトする前に、出力のコピーをファイルにキャプチャして、ライブで見ることができます。

ただし、これを cron 経由で実行する場合は、stderr にエラー以外の内容を書き込まないことをお勧めます。そうしないと、cron が実行されるたびに警告メールが送信されます。

于 2013-01-07T18:14:57.723 に答える
0

最後の答えは近かったと思います:

これのいずれか:

shell_exec('lftp -blah |& tee ' . $lfOutfile );
shell_exec('tar -blah |& tee ' . $tarOutfile );

または、それでもうまくいかない場合は、次のことを試してください。

shell_exec('lftp -blah 2>&1 | tee ' . $lfOutfile );
shell_exec('tar -blah 2>&1 | tee ' . $tarOutfile );
于 2013-03-10T22:23:16.360 に答える