UNIX — Запрашивает пользователя для ввода внутри удаленного SSH

#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 Я действительно нашел практический способ сделать это … ознакомьтесь с ОКОНЧАТЕЛЬНЫМ ОБНОВЛЕНИЕМ.