Linux ожидает, что не вернет управление сценарию bash после использования взаимодействия

Моя цель - автоматизировать следующие

  • Из основного сценария оболочки войдите в удаленный сеанс SSH (ключ без пароля уже активирован)
  • Затем мне нужен root-доступ, поэтому я использую ожидание входа в систему, то есть отправить «su», ожидать «Пароль:», отправить «», что работает.
  • Затем я хочу передать управление ожидаемому сценарию bash, который вызывал ожидаемый сценарий, и запускать различные команды SSH, входящие в систему как root.

Возможно ли это или мне нужно все делать через ожидать?


person mgibson    schedule 25.05.2016    source источник
comment
Что не работает? Покажите доказательства, которые мы можем видеть. Обычно полезно запустить ожидание с включенной отладкой, чтобы вы могли видеть, что происходит (expect -d script.exp)   -  person glenn jackman    schedule 25.05.2016


Ответы (1)


Проблема в том, что различные уровни коммуникации должны оставаться на своих местах; происходит нечто большее, чем вы думаете.

Ваша модель такая:

+------+   expect   +-----+   su   +----------------+
| bash | ---------> | ssh | -----> | remote-context | 
+------+            +-----+        +----------------+

Но на самом деле происходит следующее:

+----------------+   +----------------------+   +----------------------------+
| local terminal |   |        expect        |   |       remote terminal      |
|                |   | +------------------+ |   | +------------------------+ |
|    +------+    |   | | virtual terminal | |   | |          bash          | |
|    | bash | -----> | |                  | |   | | +--------------------+ | |
|    +------+    |   | |     +-----+      | |   | | |         su         | | |
|                |   | |     | ssh | ---------> | | | +----------------+ | | |
+----------------+   | |     +-----+      | |   | | | | remote context | | | |
                     | +------------------+ |   | | | +----------------+ | | |
                     +----------------------+   | | +--------------------+ | |
                                                | +------------------------+ |
                                                +----------------------------+

Или что-то в этом роде (например, я опустил большую часть битов, связанных с сетью). Происходит много наслоений, о большинстве из которых вы не подозреваете. Но поскольку ssh выполняется внутри expect (чтобы воспользоваться возможностями автоматизации), это означает, что ssh работает в локальном виртуальном терминале, управляемом expect; bash не может взять на себя управление напрямую, а expect не может выйти из цикла (поскольку bash не знает, как быть ведущей стороной виртуального терминала; expect и sshd знают, что ).

Вместо этого вам нужно либо напрямую написать оставшуюся часть вашего кода внутри expect, либо предоставить код, который должен запускаться в качестве аргумента (в некотором смысле; возможно, извлеченный из файла?), Который он может передать через send.

Expect получает аргументы от переменной argv, может использовать gets stdin для чтения строки текста от вызывающей стороны и _15 _ / _ 16 _ / _ 17_ для извлечения содержимого файла.


Вы знаете sudo как альтернативу su? Это можно настроить, чтобы разрешить работу без пароля для конкретного запрашивающего пользователя. Это может быть полезно для обеспечения работы системы, не открывая слишком большую дыру в безопасности. Вам также следует подумать о переходе на форму ssh, которая лучше подходит для автоматизации, например:

spawn ssh $remotehost sudo /usr/local/bin/DoTheWonderfulThing

Такие вещи, когда они работают, имеют меньше деталей, которые могут неожиданно выйти из строя ...

person Donal Fellows    schedule 25.05.2016
comment
Спасибо, это отличный обзор проблемы, с которой я столкнулся. Попробую некоторые из этих предложений! - person mgibson; 26.05.2016