在兼容posix的shell上,在ssh中转义传递参数的最有效方法是什么?

时间:2011-12-10 23:07:13

标签: ssh escaping posix dash-shell

有时你想在通过ssh将它传递给shell之前可靠地转义某些东西。很奇怪这个问题看起来有多困难。 : - $

是否有更短或更有效的方法来定义此函数,因此它适用于任何严格符合posix的shell?

function sshesc () { printf "%s" "$1" | sed -e "s|'|\'\\\\\'\'|g" -e "s|^|'|" -e "s|$|'|"; }

(简单地使用echo而不是printf可能会引入错误。)

3 个答案:

答案 0 :(得分:1)

你能用Perl吗?

如果您需要经常这样做,Perl模块Net::OpenSSH可以让您的生活更轻松。

例如:

#!/usr/bin/perl
use Net::OpenSSH;

my $ssh = Net::OpenSSH->new('host');
$ssh->error and die "ssh connection failed: " . $ssh->error;

$ssh->system('ls /*');                      # the remote shell expands '/*'

$ssh->system('echo', '* $how are you! *');  # like calling execvp(3) on the
                                            # remote machine, as if no remote
                                            # shell were involved at all

答案 1 :(得分:1)

据我所知,没有。这是我见过的最短的shell引用实现。如果你不想依赖sed,你可以do it in pure shell,但这样更冗长(也更慢)。

据我所知,符合POSIX标准的shell并非普遍可用(嗨,Solaris!)。如果你愿意将你的要求提升到bash而不是破折号,你可以说:

sshesc () { printf "%q" "$1" }

(也适用于zsh!)

答案 2 :(得分:0)

在Bash中,你可以这样做:

$ printf '%q' 'echo "argument with    spaces"'

在POSIX shell中,%q的{​​{1}}未定义。我最近开始使用类似于你的sed脚本:

printf

这个想法将文本括在$ printf '%s' 'echo "argument with spaces"' | sed -e "s/'/'\\\\''/g" -e "1 s/^/'/" -e "$ s/$/'/" 中。然后你只需要逃离已经存在的'

我也将它用作可执行文件:

'

时间会显示它是否可行。

我已经遇到several projects来解决这个问题,尽管其中大部分看起来都太复杂了。这就是我最终制作自己的原因。