Как передать произвольные аргументы команде, выполняемой через SSH?

Предположим, у меня есть скрипт со следующим содержимым, расположенным в ~/echo.sh на удаленном сервере example.com:

#!/usr/bin/env bash
echo "Arg 1: $1"
echo "Arg 2: $2"
echo "Arg 3: $3"
echo "Arg 4: $4"

Теперь на моей локальной машине у меня есть другой скрипт, remote-echo.sh со следующим содержанием:

#!/usr/bin/env bash
ssh example.com "~/echo.sh $*"

Идея состоит в том, что пользователь должен иметь возможность запустить remote-echo.sh с любыми аргументами, и эти аргументы должны быть направлены ~/echo.sh на удаленном сервере.

К сожалению, это не работает:

$ ./remote-echo.sh "arg with space" "argwith\"quote" "arg3"
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file

Как это исправить? Я уже пытался использовать $@ вместо $*, но это никак не повлияло на результат.

1 ответ

Необходимо убедиться, что все аргументы, встроенные в строку, переданную в SSH, должным образом экранированы, чтобы они не интерпретировались оболочкой на удаленном сервере. Самый простой способ сделать это с помощью %q форматировать символы для printf в Баш:

#!/usr/bin/env bash
ssh example.com "~/echo.sh $(printf "%q " "$@")"

Согласно help информация для printf в Bash:

В дополнение к стандартным спецификациям формата, описанным в printf(1), printf интерпретирует:

[...]

% q заключить аргумент в кавычки таким образом, чтобы его можно было использовать в качестве ввода оболочки

Это должно решить проблему, которую вы видите здесь, и гарантировать, что каждый аргумент передается правильно echo.sh,

Другие вопросы по тегам