Каков наиболее эффективный способ избежать передачи переданных параметров в ssh в оболочке, совместимой с posix? - PullRequest
2 голосов
/ 11 декабря 2011

Иногда вы хотите надежно избежать чего-то перед тем, как передать его в оболочку через ssh. Любопытно, насколько трудной кажется эта проблема. : - $

Есть ли более короткий или иной более эффективный способ определения этой функции, чтобы она работала с любой строго посикс-совместимой оболочкой?

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

(Простое использование echo вместо printf может привести к ошибке.)

Ответы [ 3 ]

1 голос
/ 10 января 2013

Насколько мне известно, нет. Это самая короткая реализация цитирования оболочки, которую я видел. Если вы не хотите зависеть от sed, вы можете сделать это в чистой оболочке , но это намного более многословно (и медленнее).

Насколько я понимаю, POSIX-совместимые оболочки доступны не везде (привет, Solaris!). Если вы хотите поднять требования к bash вместо dash, вы можете просто сказать:

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

(также работает в zsh!)

1 голос
/ 12 декабря 2011

Можете ли вы использовать 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
0 голосов
/ 07 ноября 2017

В Bash вы можете сделать:

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

В оболочке POSIX %q из printf не определено.Недавно я начал использовать скрипт 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/$/'/

Время покажет, является ли оно жизнеспособным.* Я столкнулся с несколькими проектами для решения этой проблемы, хотя большинство из них показались мне слишком сложными на мой вкус.Вот почему я сделал свой собственный.

...