2013-01-07 49 views
0

我正在使用Linux本地計算機,需要定期備份/鏡像一些非常大的文件結構。我只能訪問SFTP。PHP LFTP數據鏡像輸出

我是一個簡單的點擊後解決方案。我最初試圖在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書籤(因爲它存儲在純文本不應該有)終端提示輸入密碼,該腳本運行後,一個很好的通知與一些信息有關的文件/文件夾/速度等

但是,當腳本是運行在終端上,只有「輸入密碼」位輸出到終端,我希望終端上顯示的所有輸出(通常會顯示什麼文件/文件夾當前正在處理等)

任何人都知道怎麼做?

+0

也許你應該抓住/輸出從你的['shell_exec()'](http://ca1.php.net/manual/en/function.shell-exec.php)調用返回?但是,這將只顯示命令完成後的輸出*。你寫劇本的方式我認爲你永遠無法看到它的存在。 – Sammitch

+0

是atm它輸出的最終結果,我雖然可能不會這樣。對於這種情況,你有什麼建議可以更好地編寫代碼嗎? – hozza

回答

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會在每次運行時發送警告郵件。

+0

我嘗試過,但它不起作用......腳本確實很好,但仍然沒有輸出到終端。 http://pastebin.com/zCeNvK1s – hozza

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);