Perl:带有'ssh -q'的rsync失败,退出代码为14

时间:2018-03-22 18:36:13

标签: perl rsync quoting

我需要从perl脚本运行rsync任务。 (下面的代码是一个更大的脚本的一部分,并且使用perl是不可避免的。)由于rsync是非交互式运行的,我想避免从我正在上传文件的服务器上打印ssh登录标题。我已经看到使用命令rsync -e 'ssh -q'是这样做的方法,这可以从命令行。 (好吧,我正在使用长选项格式--rsh='ssh -q'来提高脚本的可读性。)

但是,我似乎无法从我的perl脚本中使用它。以下是代码的相关部分:

#!/usr/bin/env perl

use strict;
use warnings;

my $src = '/path/to/myfile';
my $dest = 'remote:/path/to/target';

my @rsync_cmd;

# this one works, returns 0
@rsync_cmd = ('rsync', '--archive', '--update', '--rsh=ssh', $src, $dest);
system(@rsync_cmd);
print "Exit code: ", $? >> 8, "\n\n";

# this one doesn't, returns 14
@rsync_cmd = ('rsync', '--archive', '--update', '--rsh=\'ssh -q\'', $src, $dest);
system(@rsync_cmd);
print "Exit code: ", $? >> 8;

第一个命令工作正常并返回0.第二个命令返回14(IPC代码中的错误)并给出以下输出:

rsync: Failed to exec ssh -q: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(85) [sender=3.1.1]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in IPC code (code 14) at io.c(226) [sender=3.1.1]

正如我所说,从命令行运行带--rsh='ssh -q'的rsync确实可以正常工作,所以我不确定这里发生了什么。我尝试过各种其他引用ssh命令的方法:

  • '--rsh="ssh -q"'
  • q{--rsh='ssh -q'}
  • q{--rsh="ssh -q"}

(加上一些),所有这些都给出相同的退出代码(14)。

我尝试过的其他事情没有成功:

  • 如果rsync无法找到ssh二进制文件,请用ssh替换/usr/bin/ssh
  • 使用短选项格式-e 'ssh -q'
  • 使用File::Rsync模块(rsync的perl包装器)尝试避免引用问题。
  • 通过RSYNC_RSH设置$ENV{'RSYNC_RSH'}=q{ssh -q}环境变量。
  • 删除--archive--update选项以进行测试。

所有这些导致相同的退出代码,14。我在我的智慧结束,请帮助。

1 个答案:

答案 0 :(得分:2)

system(..., "--rsh=ssh -q", ...)

您正在使用system LIST语法,该语法已将未插入的每个参数传递给被调用程序。来自Perl的"--rsh=ssh -q"相当于shell中的--rsh='ssh -q'。引号会将ssh-q视为命令的同一参数的一部分,但引号本身将在shell中插入,因此rsync将接收参数为--rsh=ssh -q