#bash #unix #ssh #sh #remote-server
#bash #unix #ssh #sh #удаленный сервер
Вопрос:
Когда я захожу на удаленный сервер с помощью SSH, я пытаюсь запросить у пользователя ввод данных о том, запускать службу или нет после выполнения некоторых задач, в то время как я пытаюсь автоматизировать процесс. Вот пример
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $srv <<EOF
if [cond1]
then
do task1
else
do task2
fi
some tasks to perform
## This part doesn't show up when run ##
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
start the service
fi
EOF
Но когда я запускаю этот скрипт автоматизации, он выполняет предыдущие задачи, но пропускает шаг запроса пользователя на запуск службы и пропускает эту задачу тоже.
Пожалуйста, помогите.
Спасибо, Sid
Комментарии:
1. Я знаю, в чем проблема, но не знаю, как ее решить.
read
хочет прочитать из stdin, который заполнен<<EOF
.
Ответ №1:
Проблема заключается в том, как вы вызываете скрипт:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $srv <<EOF
...
EOF
Здесь вы используете stdin для отправки самого скрипта. Итак, откуда read
предполагается чтение? На самом деле у меня нет sshpass, поэтому я не могу проверить это напрямую, но это работает с ssh и доверенным ключом:
ssh <your ssh options> '
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
'
Теперь вы отправляете скрипт в виде строки, оставляя stdin свободным для интерактивного использования. Я не могу видеть весь ваш скрипт, так что это может вызвать другие проблемы, если ваш скрипт действительно использует '
в вашем скрипте.
Обновить
Вы можете избежать проблемы с одинарными кавычками, сохранив команды в файле сценария. Допустим a.sh
:
ssh <your ssh options> "$(< a.sh)"
Это отправит подробную команду в команду ssh, не беспокоясь о расширении переменной или о чем-либо еще.
Обновление 2
Если мы пытаемся избежать сохранения сценария в файл, вы все равно можете использовать опцию одинарных кавычек. Способ обойти существующие одинарные кавычки состоял бы в том, чтобы изменить каждое вхождение на это: '''
. Таким образом, по сути, он завершает строку в одинарных кавычках, добавляет одинарную кавычку к самой строке, а затем повторно открывает строку в одинарных кавычках. Без пробела там все равно одна строка. Вот пример, если в вашей строке чтения использовались одинарные кавычки вместо двойных:
ssh <your ssh options> '
read -p '''Are you sure you want to start the service? Enter (Y/y or N/n)''' -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
'
Обратите внимание, как подсветка синтаксиса Stackoverflow правильно анализирует это и как бы иллюстрирует то, что я пытался сказать. Я бы перевел как можно больше ваших одинарных кавычек в двойные кавычки, чтобы уменьшить сложность здесь.
Вы также можете использовать двойные кавычки вместо одинарных кавычек. Проблема сейчас в том, что интерпретатор bash может манипулировать вашей строкой до того, как она пройдет через ssh. Чтобы избежать этого, вам нужно будет избегать всех расширений, а также существующих двойных кавычек. Вот так:
ssh <your ssh options> "
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
"
Опять же, чтобы избежать сложностей с этим методом, переведите как можно больше ваших двойных кавычек в одинарные кавычки.
ОКОНЧАТЕЛЬНОЕ ОБНОВЛЕНИЕ
Вы можете использовать исходную строку как есть, используя комбинацию подстановки команд, cat и here doc без расширения:
ssh <your ssh options> "$(cat <<'EOF'
read -p "Are you sure you want to start the service? Enter (Y/y or N/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo hi
fi
EOF
)"
Обратите внимание, что этот метод фактически обманул подсветку синтаксиса Stackoverflow, но он работает.
Комментарии:
1. Привет, Джейсон, спасибо за ответ. Можем ли мы использовать любой другой символ вместо ‘. Мои скрипты используют ‘ много раз, что приводит к внезапному завершению скрипта.
2. Спасибо за это, Джейсон. Это, безусловно, имеет смысл. Но могу ли я сделать это без создания a.sh файлы?? Есть ли способ сделать это напрямую??
3. @SiddharthGandhi Я снова обновил свой ответ. На самом деле нет чистого способа сделать это, но это возможно.
4. @SiddharthGandhi Я действительно нашел практический способ сделать это … ознакомьтесь с ОКОНЧАТЕЛЬНЫМ ОБНОВЛЕНИЕМ.