Как выполнить интерактивный многострочный сценарий bash удаленно через ssh, который имеет оболочку csh по умолчанию? - PullRequest
0 голосов
/ 12 октября 2018

Я пишу скрипт, который дал бы мне возможность удаленно выполнять другие локальные скрипты bash по SSH без их загрузки.Некоторые из моих серверов имеют Linux, некоторые FreeBSD с csh по умолчанию.До сих пор я пришел к следующему:

ssh remote_server 'bash -c '\'"$(cat local_script.sh)"\'' script_parameters'

Это позволяет мне выполнять local_script.sh на remote_server, поддерживает интерактивность (например, команда «read» будет работать в local_script.sh), иЯ могу передать позиционные параметры в скрипт.Проблема в том, что если local_script.sh имеет несколько строк, приведенный выше код работает только для удаленных серверов с оболочкой bash по умолчанию.На FreeBSD sshd сначала запускает csh, чтобы выполнить команду «bash -c», и пытается передать код сценария (результат $ (cat local_script.sh)) ему в качестве первого параметра.Но поскольку этот код является многострочным, и csh хочет, чтобы заключительная кавычка была в той же строке, что и начальная кавычка, я получаю «Unmatched».ошибка.Поэтому csh просто не может разобрать этот экранированный многострочный параметр, чтобы передать его процессу bash.

Единственное решение, которое я вижу сейчас, - это синтаксический анализ local_script.sh и автоматическая перезапись его в однострочник с помощью ";»разделители перед передачей через SSH.Но это требует создания другого сценария и, кажется, не так просто.Поэтому я хотел бы спросить, можно ли как-нибудь решить эту проблему с синтаксическим анализом csh miltiline?

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

В этом конкретном случае нет необходимости сохранять самые внешние кавычки.

ssh remote_server bash -c "\"$(cat local_script.sh)\"" script_parameters

Это не совсем надежно;например, одинарные кавычки в local_script.sh не будут заключать в кавычки текст.Таким образом, в следующем примере

echo 'fnord "$(echo yes)"'

подстановка команды будет оцениваться удаленно, даже если строка заключена в одинарные кавычки.В общем случае вам придется заменить cat, в основном, синтаксическим анализатором оболочки, который идентифицирует конструкции, которые необходимо экранировать.

0 голосов
/ 12 октября 2018

Как насчет использования стандартного ввода /dev/stdin?

ssh remote_server bash /dev/stdin script_parameters < local_script.sh

Использование двух разных команд и временного файла

bash

ssh remote_server $'tmp=`mktemp tmp.XXXXXX`;cat <<\'HEREDOC_END\' >"$tmp"
'"$(cat local_script.sh)"'
HEREDOC_END
bash "$tmp" script_parameters ;rm "$tmp"'

csh

ssh remote_server 'set tmp=`mktemp tmp.XXXXXX`;cat <<"HEREDOC_END" >"$tmp"
'"$(cat local_script.sh)"'
"HEREDOC_END"
bash "$tmp" script_parameters ;rm "$tmp"'
...