有时你想在通过ssh将它传递给shell之前可靠地转义某些东西。很奇怪这个问题看起来有多困难。 : - $
是否有更短或更有效的方法来定义此函数,因此它适用于任何严格符合posix的shell?
function sshesc () { printf "%s" "$1" | sed -e "s|'|\'\\\\\'\'|g" -e "s|^|'|" -e "s|$|'|"; }
(简单地使用echo而不是printf可能会引入错误。)
答案 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/$/'/"
中。然后你只需要逃离已经存在的'
。
我也将它用作可执行文件:
'
时间会显示它是否可行。