Для ясности, здесь работают 3 оболочки - та, которая интерпретирует ssh, вашу локальную оболочку; тот, который ssh
будет автоматически запущен для вас, и bash
, который вы вызываете явно.
Причина, по которой «исчезает» 1, состоит в том, что оболочка, которая интерпретирует команду ssh
, «съедает» кавычки вокруг аргументов -c
, а затем оболочку на другой стороне ssh
разбивает аргументы в пробелах. Так что это выглядит как bash -c echo 1 ; echo 2; echo 3
. В свою очередь, -c
просто получает echo
, что отображает пустую строку; 1
становится значением $1
этой оболочки, которое не используется. Затем возвращается внутренний bash
, а прямая оболочка ssh
нормально запускает echo 2; echo 3
.
Учтите это:
$ ssh xxx bash -c "'echo 1'; echo 2; echo 3"
1
2
3
где echo 1
защищено в аргументах ssh, поэтому оболочка ssh 2-го уровня передается bash -c 'echo 1'; echo 2; echo 3
. Внутренняя оболочка 3-го уровня эхосигнала 1, а затем оболочка ssh 2-го уровня эхосигналов 2 и 3.
Вот еще одна интересная перестановка:
$ ssh xxx bash -c "'echo 1; echo 2; echo 3'"
1
2
3
здесь, внутренняя оболочка получает все эхо, поскольку они сгруппированы в первой оболочке на "
и во второй оболочке на '
.
В общем, сценарии оболочки для передачи аргументов сценариям оболочки, которые запускают сценарии оболочки, довольно сложно создавать. Я бы посоветовал вам немного изменить технику, чтобы сэкономить много усилий. Вместо этого вы можете рассмотреть возможность использования конвейера, который позволяет избежать рекурсивной интерпретации оболочки:
$ echo "echo 1; echo 2; echo 3" | ssh -T xxx
1
2
3
(Здесь -T
просто для подавления ssh с жалобами на отсутствие псевдотерминала).