这个问题找了好久,没有找到满意的答案。
我有一个 perl 脚本,需要将文件从一台主机复制到另一台主机,本质上
sub copy_file{
my($from_server, $from_path, $to_server, $to_path, $filename) = @_;
my $from_location = "$from_server:\"\\\"${from_path}${filename}\\\"\"";
my $to_location = $to_path . $filename;
$to_location =~ s/\s/\\\\ /g;
$to_location = "${to_server}:\"\\\"${to_location}\\\"\"";
return system("scp -p $from_location $to_location >/dev/null 2>&1"");
}
问题是,我的一些文件名如下所示:
BLAH;BLAH;BLAH.TXT
Some really nicely named file( With spaces, prentices, &, etc...).xlx
我已经在处理空格了,它的代码非常难看,因为在每一方,文件可以是本地的或远程的,并且转义对于 scp 调用的 from 和 to 部分是不同的。
我真正想要的是要么以某种方式转义所有可能的特殊字符,要么通过使用 POSIX 系统调用以某种方式完全绕过 shell 扩展。如果需要,我可以编写 XS 模块。
我在 .ssh 目录中设置了正确的 key
此外,我也不确定哪些特殊字符会和不会引起问题。我想支持所有合法的文件名字符。
最佳答案
假设您想使用 foo(s)
复制文件 scp
。
如下所示,scp
将源和目标视为 shell 文字,因此您将以下参数传递给 scp
:
scp
-p
--
host1.com:foo\(s\)
或 host1.com:'foo(s)'
host2.com:foo\(s\)
或 host2.com:'foo(s)'
您可以使用
system
的多参数语法加上转义函数来做到这一点。use String::ShellQuote qw( shell_quote );
my $source = $from_server . ":" . shell_quote("$from_path/$filename");
my $target = $to_server . ":" . shell_quote("$to_path/$filename");
system('scp', '-p', '--', $source, $target);
如果你真的想构建一个 shell 命令,像往常一样使用
shell_quote
。my $cmd = shell_quote('scp', '-p', '--', $source, $target);
$ ssh [email protected] 'mkdir foo ; touch foo/a foo/b foo/"*" ; ls -1 foo'
*
a
b
$ mkdir foo ; ls -1 foo
$ scp '[email protected]:foo/*' foo
* 100% 0 0.0KB/s 00:00
a 100% 0 0.0KB/s 00:00
b 100% 0 0.0KB/s 00:00
$ ls -1 foo
*
a
b
$ rm foo/* ; ls -1 foo
$ scp '[email protected]:foo/\*' foo
* 100% 0 0.0KB/s 00:00
$ ls -1 foo
*
关于perl - 以编程方式带有特殊字符的 scp,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22948664/