有时您想在通过 ssh 将某些内容传递给 shell 之前可靠地转义某些内容。很好奇这个问题看起来有多困难。:-$
是否有更短或更有效的方法来定义此函数,因此它可以与任何严格符合 posix 的 shell 一起使用?
function sshesc () { printf "%s" "$1" | sed -e "s|'|\'\\\\\'\'|g" -e "s|^|'|" -e "s|$|'|"; }
(简单地使用 echo 而不是 printf 可能会引入错误。)
有时您想在通过 ssh 将某些内容传递给 shell 之前可靠地转义某些内容。很好奇这个问题看起来有多困难。:-$
是否有更短或更有效的方法来定义此函数,因此它可以与任何严格符合 posix 的 shell 一起使用?
function sshesc () { printf "%s" "$1" | sed -e "s|'|\'\\\\\'\'|g" -e "s|^|'|" -e "s|$|'|"; }
(简单地使用 echo 而不是 printf 可能会引入错误。)
Can you use Perl?
If you need to do this frequently, the Perl module Net::OpenSSH could make your live far easier.
For instance:
#!/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
据我所知,没有。这是我见过的最短的 shell 引用实现。如果您不想依赖 sed,您可以在纯 shell中执行此操作,但这样会更加冗长(并且速度较慢)。
据我了解,符合 POSIX 标准的 shell 并非普遍可用(嗨,Solaris!)。如果您愿意将要求提高到 bash 而不是 dash,您可以说:
sshesc () { printf "%q" "$1" }
(也适用于 zsh!)
在 Bash 中,您可以执行以下操作:
$ printf '%q' 'echo "argument with spaces"'
在 POSIX shell 中,%q
ofprintf
没有定义。我最近开始使用类似于您的 sed 脚本:
$ printf '%s' 'echo "argument with spaces"' | sed -e "s/'/'\\\\''/g" -e "1 s/^/'/" -e "$ s/$/'/"
这个想法是将文本附在'
. 然后你只需要逃避'
已经存在的东西。
我还将它用作可执行文件:
#!/bin/sed -f
# usage: $0
# make this:
#
# echo "'special chars'"
#
# into this:
#
# 'echo "'\''special chars'\''"'
#
# escape all '
s/'/'\\''/g
# enclose in '
1 s/^/'/
$ s/$/'/
时间会证明它是否可行。
我遇到了几个解决这个问题的 项目,尽管大多数项目对我来说似乎太复杂了。这就是为什么我最终自己做的。