2

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

是否有更短或更有效的方法来定义此函数,因此它可以与任何严格符合 posix 的 shell 一起使用?

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

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

4

3 回答 3

1

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
于 2011-12-12T08:54:31.593 回答
1

据我所知,没有。这是我见过的最短的 shell 引用实现。如果您不想依赖 sed,您可以在纯 shell中执行此操作,但这样会更加冗长(并且速度较慢)。

据我了解,符合 POSIX 标准的 shell 并非普遍可用(嗨,Solaris!)。如果您愿意将要求提高到 bash 而不是 dash,您可以说:

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

(也适用于 zsh!)

于 2013-01-10T04:52:22.980 回答
0

在 Bash 中,您可以执行以下操作:

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

在 POSIX shell 中,%qofprintf没有定义。我最近开始使用类似于您的 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/$/'/

时间会证明它是否可行。

我遇到了几个解决这个问题的 项目,尽管大多数项目对我来说似乎太复杂了。这就是为什么我最终自己做的。

于 2017-11-07T14:28:53.777 回答