Для каждого прыжка вам понадобится слой цитирования. По сути, в ssh server some command foo bar
конечном итоге работает $SHELL
с аргументами -c
и some command foo bar
, таким образом:
- Первый слой кавычек удаляется вашей локальной оболочкой, где вы выполнили команду ssh, и
- Каждый последующий переход вызывает оболочку, которая удаляет еще один уровень цитирования.
Это, в свою очередь, означает, что операции оболочки, такие как раскрытие переменных, перенаправление, раскрытие с использованием подстановочных знаков, нуждаются в дополнительных кавычках для предотвращения воздействия на них промежуточных оболочек.
Например, если у меня были файлы foo-a
и foo-?
в моем домашнем каталоге:
$ touch foo-a foo-\? $ echo foo-* foo-? foo-a $ ssh Server1 echo foo-* foo-? foo-a foo-a # foo-* expanded locally to foo-? foo-a, foo-? expanded again remotely $ ssh Server1 'echo foo-*' foo-? foo-a # foo-* expanded remotely to foo-? foo-a $ ssh Server2 ssh Server1 'echo foo-*' foo-? foo-a foo-a # foo-* expanded remotely to foo-? foo-a, foo-? expanded again remotely in the next hop $ ssh Server2 "ssh Server1 'echo foo-*'" foo-? foo-a # foo-* expanded in the last hop
Было бы проще, если бы вы использовали ProxyCommand
или ProxyHost
. Это создаст туннель между двумя системами вместо создания пахлавы оболочек, выполняющих команды:
~ ssh -o ProxyCommand='ssh Server2 nc %h %p' Server1 'echo foo-*' foo-? foo-a ~ ssh -J Server2 Server1 'echo foo-*' foo-? foo-a