Ожидать: «отсутствует закрывающая скобка» и ошибка отправки команды

#bash #shell #ssh #expect

#bash #оболочка #ssh #ожидать

Вопрос:

Я пытаюсь запустить сценарий ожидания, который отправляется на другое локальное устройство для установки и запуска скрипта python. Все переменные определены вне скрипта:

 set prompt "$SSHuser@$SSHname:~$"
spawn ssh -o "StrictHostKeyChecking no" $SSHuser@$SSHhost
expect
{
  "*assword"
  {
    send "$SSHpasswordr"
    exp_continue
  }
  "$prompt"
  {
    send "sudo su"
    expect
    {
      "*assword"
      {
        send "$SSHpasswordr"
        exp_continue
      }
      "$prompt"
      {
        send "apt update amp;amp; apt upgrade -y amp;amp; apt install net-tools -y amp;amp; apt install python3-pip -y"
        expect "$prompt"
        {
        send "wget -O script.py https://SOMEURL"
        }
      }
    }
  }
}
  

Тем не менее, я продолжаю получать следующий вывод / ошибку:

 missing close-brace
    while executing
"{"
couldn't read file "sur
    expect
    {
      *assword
      {
        send REDACTEDPASSWORD
        exp_continue
      }
      
      {
        send -- apt": no such file or directory
spawn ssh -o StrictHostKeyChecking no USERNAME@192.168.1.173
USERNAME@192.168.1.173's password: 
  

Я подсчитал скобки и использовал инструменты выделения, и я не вижу никаких отсутствующих скобок.
Я также не понимаю, почему он продолжает читать «отправить «sudo su r» как «sur».
Моя способность ожидать все еще довольно ограничена.
Я был бы очень признателен за любую помощь в понимании того, что здесь пошло не так.

Комментарии:

1. Вам нужна обратная косая черта в конце expect строк, чтобы следующая строка обрабатывалась как часть той же команды. См . tcl.tk/man/tcl8.6/TclCmd/Tcl.htm подробнее о том, как анализируется tcl.

2. Я не уверен, что вы также можете вложить expect подобные вызовы, но я намного лучше знаком с tcl в целом, чем ожидал.

3. вы думали об использовании ansible? существуют модули ansible, такие как expect или apt. С помощью ansible вы выполняете скрипты python на удаленных машинах с помощью ssh-соединений. см. docs.ansible.com/ansible/latest/collections/ansible/builtin /…

4. Если вы используете аутентификацию с открытым ключом SSH и правильно настроили sudo, больше нет необходимости использовать expect .

5. Взгляните на мой sexpect (ожидание для оболочек) , который вы можете использовать для написания ожидаемых сценариев только с кодом оболочки .

Ответ №1:

Tcl заставляет вас использовать «один истинный стиль фигурной скобки», потому что новые строки являются завершителями команд.

В качестве комментария ожидаемый код не обязательно должен быть настолько глубоко вложенным. Этот код может быть записан как

 set prompt "$SSHuser@$SSHname:~$"

spawn ssh -o "StrictHostKeyChecking no" $SSHuser@$SSHhost
expect {
  "*assword" {
    send "$SSHpasswordr"
    exp_continue
  }
  "$prompt"
}

send "sudo su"
expect {
  "*assword" {
    send "$SSHpasswordr"
    exp_continue
  }
  "$prompt"
}

send "apt update amp;amp; apt upgrade -y amp;amp; apt install net-tools -y amp;amp; apt install python3-pip -y"
expect "$prompt"

send "wget -O script.py https://SOMEURLr"
expect "$prompt"

# assuming you want to exit here
send "exitr"
expect eof
  

По сути, за каждым появлением или отправкой должно следовать ожидание.