Проблемы с завершением соединения после запуска скриптов на удаленном компьютере с помощью скрипта оболочки

Это первый раз, когда я пишу сценарий оболочки. Я пытался провести как можно больше исследований, чтобы избежать глупых/повторяющихся вопросов. Пожалуйста, извините, если это повтор/тупой вопрос.

У меня есть сценарий оболочки, который подключается к удаленной машине Linux и запускает там сценарии. Я использую «ожидание» для создания ssh-соединения и выдачи команд для запуска задания. Однако у меня возникают проблемы при закрытии соединения после завершения задания.

Это мой сценарий:

set prompt "(%|#|\\$|%\]) $"


    expect -c 'spawn ssh $UN@$STAGE ;
                    expect password ; send "$PASS \n";
                    expect -regexp "$PROMPT"; send "./settings.$UN.sh > settings_log.txt \n";
                    interact'

Этот сценарий успешно запускает файл сценария для меня (параметры $UN и $STAGE являются входными для сценария. Я опустил их здесь для простоты). Тем не менее, это оставляет меня с открытым соединением. Я попытался закрыть соединение после запуска скрипта, используя следующее вместо вышеуказанного

expect -c 'spawn ssh   $UN@$STAGE ;
                expect password ; send "$PASS \n";
                expect -regexp "$PROMPT"; send "./settings.$UN.sh > settings_log.txt \n";
                expect -regexp "$PROMPT"; send "exit \n"'

Это закрывает соединение, но я заметил, что мой файл сценария вообще не запускается. Также settings_log.txt вообще не создается.

Означает ли это, что команда выхода прерывает процесс до его завершения? Я пытался использовать «сон» перед выходом, но это не помогло. Есть ли лучший способ разорвать соединение при использовании ожидания? Любая помощь приветствуется.


person PraveenGorthy    schedule 02.02.2011    source источник
comment
Можете ли вы объяснить мне, что делает expect -regexp $PROMPT? Я не знаком с expect.   -  person user359996    schedule 02.02.2011
comment
Это первый раз с ожидаемым. expect -regexp $PROMPT ожидает, пока оболочка завершит свою работу, которая и вернется для пользовательского ввода. Например, я запускаю ssh-соединение, используя . ожидать -c 'порождать ssh $UN@$STAGE ; Теперь я знаю, что ssh запросит пароль. Поскольку я знаю это заранее, я могу сказать своему сценарию, чтобы он был готов к этому, и отправить пароль, когда это произойдет. Это достигается с помощью следующего оператора. ожидать пароль ; отправить $PASS \n Вы также можете указать регулярное выражение для ожидания. Это то, что я пытался сделать. Я определил переменную ($ PROMPT) вверху и использовал ее в следующем выражении.   -  person PraveenGorthy    schedule 03.02.2011


Ответы (3)


с expect вы завершаете свои команды отправки с помощью \r, а не \n, поэтому

 expect -c 'spawn ssh   $UN@$STAGE
            expect password
            send "$PASS\r"
            expect -regexp "$PROMPT"
            send "./settings.$UN.sh > settings_log.txt\r"
            expect -regexp "$PROMPT"
            send "exit\r"
            expect eof'
person glenn jackman    schedule 03.02.2011

Обратите внимание, что вы можете выполнять команды удаленной оболочки и копировать файлы с помощью ssh и scp напрямую, без использования expect.

Например,

scp ./settings.$UN.sh $UN@$STAGE:settings_log.txt
ssh $UN@$STAGE whatever-you-need-to-execute

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

person user359996    schedule 02.02.2011
comment
Я пытался это сделать. Но ssh $UN@$STAGE запрашивает пароль. Мне нужно, чтобы этот скрипт работал без вмешательства пользователя. Скажем, если я могу создать HTML-форму для пользователя, в которой он вводит свои UN и PWD, я хочу, чтобы моя система запускала этот скрипт. Я не могу это сделать, ssh запрашивает PWD. Итак, я использую кроме. - person PraveenGorthy; 03.02.2011
comment
Вы можете идентифицировать себя с помощью сертификата, использовать expect для предоставления пароля ssh или использовать sshpass, чтобы сделать это за вас. Обратите внимание, что первый вариант является наиболее безопасным, а также работает для scp (как и второй, но менее безопасный). - person user359996; 03.02.2011
comment
Ок, отлично. Это звучит как лучший способ сделать это. Спасибо за помощь - person PraveenGorthy; 03.02.2011

Ваш внешний скрипт, похоже, написан на csh и устанавливает переменную с именем «prompt», но ваш expect скрипт использует переменную с именем «PROMPT». Попробуйте сделать так, чтобы имена двух переменных соответствовали регистру.

person Dennis Williamson    schedule 02.02.2011
comment
несоответствие регистра было моей опечаткой. в моем реальном сценарии оба в одном и том же случае - person PraveenGorthy; 03.02.2011