什么 perl 脚本将 scp 目录名称中包含空格?

什么 perl 脚本将 scp 目录名称中包含空格?

我已经尝试了几个小时来弄清楚如何让 perl 进入scp名称中带有空格的目录。我目前收到错误

scp: ambiguous target

这是不起作用的脚本:

#!/usr/bin/perl
# Assuming you already have passwordless ssh setup from some account to root on HOST
# On HOST, setup test files and directories
# root@HOST$ mkdir /tmp/from/spaced\ mydir
# root@HOST$ touch /tmp/from/spaced\ mydir/t1
# root@HOST$ mkdir /tmp/to

my $HOST='localhost';
my $escaped_component_name = 'spaced mydir';

# try to form scp from-arg that will preserve the space
# in the directory name by escaping whitespace with backslash
$escaped_component_name =~ s/(\s)/\\$1/g;
my $scp_from = '/tmp/from/'.$escaped_component_name.'/*';
my $scp_to = '/tmp/to/'.$escaped_component_name;

system 'scp', '-vr', '--', 'root@'.$HOST.':'.$scp_from, 'root@'.$HOST.':'.$scp_to;

有人看到我做错了什么吗?

答案1

我究竟做错了什么?

使用system。这将分叉一个 shell,并将其余参数作为选项。换句话说,sh就是吃引用。

尝试:

system 'scp', '-vr', '--', '"root@'.$HOST.':'.$scp_from.'"', '"root@'.$HOST.':'.$scp_to.'"' ;`

答案2

首先,您确定scp支持远程到远程传输吗?据我所知,有些版本是通过开关来实现的-3

不管怎样,每当我遇到参数问题时,我都会把这个脚本放在手边:

#!/usr/bin/perl
my $count;
for (@ARGV) {
  s/([\x00-\x1F\x7F])/'\x'.unpack('H*',$1)/ge;
  printf "%d: '%s'\n", ++$count, $_;
}

让我们试试你的代码:

$ perl
my $HOST='localhost';
my $escaped_component_name = 'spaced mydir';

# try to form scp from-arg that will preserve the space
# in the directory name by escaping whitespace with backslash
$escaped_component_name =~ s/(\s)/\\$1/g;
my $scp_from = '/tmp/from/'.$escaped_component_name.'/*';
my $scp_to = '/tmp/to/'.$escaped_component_name;
system 'sandbox/args.pl', '-vr', '--', 'root@'.$HOST.':'.$scp_from, 'root@'.$HOST.':'.$scp_to;
# (Control-D)
1: '-vr'
2: '--'
3: 'root@localhost:/tmp/from/spaced\ mydir/*'
4: 'root@localhost:/tmp/to/spaced\ mydir'

是的,转义很好 - 我的版本scp需要目标路径中的反斜杠(但不在本地路径中);我想这与ssh幕后运作有关。

让我们用真实的东西来尝试一下:

$ perl
$local_dir = "some dir/";
$remote_dir = "/tmp/some dir/";
$remote_dir  =~ s/(\s)/\\$1/g;
system 'scp', $local_dir."login.sql", 'user@host:'.$remote_dir;

# (Control-D)
login.sql            100% |********************************************|   434       00:00

答案3

这是对我有用的最终脚本。感谢@Ricky Beam 和@arielCo 的意见。使用文件::规范;

      my $escaped = $component_name;
      $escaped =~ s/(\s)/\\$1/g;

      # scp-from-path
      my $scp_from = File::Spec->catdir($REMOTE_MV_HOME, $escaped,'*');

      # scp-to-path
      my $scp_to = File::Spec->catdir($REMOTE_MV_HOME, $escaped, '\.');

      # use double-quotes on only the to-path because
      # of the double-shelling (local fork of 'sh' and then the remote execution 'sh')

      system 'scp', '-vr', '--', 'root@'.$HOST.':'.$scp_from, 'root@'.$HOST.':"'.$scp_to.'"' ;

相关内容