在perl中使用`rsync`和`ssh`导致无法解释的超时?

时间:2013-12-08 18:54:49

标签: linux perl ssh rsync

我正在对大量文件运行两个阶段的过程。

代码:

$server_sleep = 1;
$ssh_check = 'ssh '.$destination_user."@".$destination_hostname.' "test -e '.$destination_path.$file_filename.'.txt && echo 1 || echo 0"';
while (`$ssh_check` ne "1\n") { # for some reason, the backticks return the 1 with a newline
   $upload_command = "/usr/bin/rsync -qogt --timeout=".$server_sleep." --partial --partial-dir=".$destination_path."partials ".$file_path."/".$file_filename.".txt ". $destination_user."@".$destination_hostname.":".$destination_path;

   sleep $server_sleep; # to avoid hammering the server (for the rsync)
   $upload_result = `$upload_command  2>&1`;
   $file_errorReturn = "FAIL" if $?;
   if (defined($file_errorReturn)) {
      #log an error. there is code to do this, but I have omitted it.
   }
   sleep $server_sleep; # to avoid hammering the server (for the ssh check)
   $server_sleep++; # increase the timeout if failures continue
}

行为: 对于前几个文件,这可以正常工作(这应该处理关于密钥,访问,权限,拼写错误等的前几个问题),并且在某些时候,我得到了这个错误:

ssh: connect to host remote_server.com port 22: Connection timed out
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(600) [sender=3.0.6]

无论我是否在命令中指定了-e ssh,我都会得到这个,所以我假设某个地方有一个默认的ssh(很好)。我也尝试过使用scp的rsync部分,导致类似的连接超时错误:

ssh: connect to host remote_server.com port 22: Connection timed out
lost connection

你可能有的问题

1)因为前几个文件有效,所以路径清晰可行(即错别字,权限等应该没有问题),我的调试代码输出实际尝试的命令,这个在命令行中工作正常(甚至在脚本中失败的文件)。

2)我曾尝试将-vvvvv添加到ssh和rsync中,但我不知道如何让它在我的脚本中输出更多的错误信息。我得到的只是上面的错误,当我在命令行上运行时,我没有错误。 (即使我将“2>& 1”和“>> log.txt”添加到两个命令的末尾。)我当然不可能收集所有的日志,所以你的帮助我也不胜感激。

3)我只是本地和远程计算机上的普通用户。

local: rsync  version 3.0.6  protocol version 30
remote: rsync  version 3.0.9  protocol version 30
path to ssh and rsync is the same on both.

4)回应评论中的优秀问题(来自qwrrty)(谢谢!): 它不是非常一致。文件被编号,它们按以下顺序运行:4,5,3,2,1。它失败了1.然后我删除了3.它仍然失败了1.当我重新放入3时,它开始了失败2。

文件都很小(最大5mb),因此传输基本上是即时的(因为机器彼此在物理或网络上相距不远)。 如果您需要更多细节,请告诉我。如果您有任何建议,请提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以尝试通过在单个rsync中完成所有操作来最小化额外的ssh会话和子进程吗?像这样的东西?

open (RSYNC, "| /usr/bin/rsync -qogt \
                  --files-from=- \
                  --ignore-existing \
                  --timeout=${server_sleep} \
                  --partial --partial_dir=${destination_path}partials \
                  ${destination_user}@${destination_hostname}:${destination_path}");
for $f (@big_list_of_files) {
    print RSYNC $f, "\n";
}
close RSYNC;
rsync内置了大量关于如何一次传输和同步大量文件的智能,根据我的经验,它通常最好让它尽可能多地完成工作。