我正在使用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书签中没有密码(不应该以明文形式存储),终端会提示输入密码,在脚本运行后,会给出一个很好的通知,其中包含一些关于文件/文件夹/的信息速度等。
但是,当脚本在终端中运行时,只有“输入密码”位输出到终端,我希望所有输出显示在终端中(通常会显示当前正在使用的文件/文件夹)等)
任何人都知道怎么做?
答案 0 :(得分: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会在每次运行时发送警告电子邮件。
答案 1 :(得分: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 );