В сценарии bash у меня есть сегмент ожидания, в котором он отправляет команды на машину через ssh. У меня там есть bash -c
, так как мне нужно установить переменные среды в этой команде.
Но я получаю сообщение об ошибке:
extra characters after close-quote
while executing
"spawn -noecho ssh -t anon@machine 'bash -c "cd /tmp;"'
"
Когда я запускаю эту команду вручную ssh -t anon@machine 'bash -c "cd /tmp;"'
, она работает нормально. Что здесь не так?
ssh_param = "-t ${scp_user}${_machine} 'bash -c \"cd /tmp;\"'"
/usr/bin/expect <<-EOF1
set timeout 360
spawn -noecho ssh ${ssh_param}
expect {
"password:" {
send "${_pass}\r"
}
eof { exit }
}
expect {
eof { exit }
}
EOF1
Кроме того, если я устанавливаю ssh_param как ssh_param = "-t ${scp_user}${_machine} \"cd /tmp;\""
, это работает, так почему же bash -c ...
приводит к сбою?
Я пишу этот сценарий для общего использования для людей, у которых могут не быть настроены открытые закрытые ключи ssh в их средах. Поэтому мне лучше использовать запрос пароля и попросить их ввести его вручную.
Взгляните на man sshpass
(поставщик неинтерактивных паролей ssh).
Ожидание предоставляет возможность включить вывод отладки. Вы можете включить это в свой сценарий, чтобы получить больше информации о том, что делает ожидаемый результат. Добавьте следующую строку в начало сценария ожидания: exp_internal 1
Мне нужно, чтобы этот сценарий можно было запускать и на компьютерах с Windows.
Вы можете запустить «expect» с опцией -d, чтобы включить режим подробной отладки из командной строки: «expect -d your_script.exp»
Сценарий представляет собой сценарий bash, часть исключений предназначена только для раздела пароля в сценарии bash. Когда я добавил exp_internal 1
, он не показывает никаких других результатов, просто та же ошибка.
Вы пытались установить exp_internal 1
в ожидаемом коде? Незадолго до этого set timeout 360
Это потому, что tcl (и, следовательно, ожидаемый) не имеет особого значения для одинарных кавычек, но имеет значение для двойных кавычек.
Я всегда предлагаю писать все это в tcl/expect вместо того, чтобы пытаться вызвать ожидаемый результат из сценария оболочки. Удаляет целый слой проблем с цитатами.
Я бы избавился от 'bash -c \"cd /tmp;\"'
и перешел в /tmp в логике expect {
.
Я удалил остальную часть команды после cd /tmp;
для поста, но мне также нужно установить переменную среды и после этого запускать другие команды. Я не могу удалить компакт-диск /tmp
Я говорю, что нужно поместить cd /tmp в ожидаемый код, а не в логику вашего ssh-соединения. настройку переменных окружения также можно выполнить таким же образом.
После того, как bash выполнит замену параметров в Heredoc, expect
запускается с помощью
set timeout 360
spawn -noecho ssh -t XXXYYY 'bash -c "cd /tmp;"'
expect {
"password:" {
send "ZZZ\r"
}
eof { exit }
}
expect {
eof { exit }
}
Скрипты expect
написаны на языке tcl
, который в основном работает путем разделения строки на слова и обработки первого слова как команды, которую нужно выполнить, а остальные слова - как аргументы после выполнения замен. Что-то вроде оболочки, но с более разумными правилами. 12 правил синтаксического анализа tcl называются Додекалог.
Одинарные кавычки не используются для группировки нескольких слов в одно — только двойные кавычки, []
(которые указывают на команду и аргументы для оценки) и {}
(которые ничего в них не заменяют и не оценивают). Итак, линия
spawn -noecho ssh -t XXXYYY 'bash -c "cd /tmp;"'
делится на spawn
, -noecho
, ssh
, -t
, XXXYYY
, 'bash
, -c
и "cd /tmp;"'
. Одинарная кавычка в конце после закрывающей двойной кавычки последнего слова является ошибкой. Обычно в tcl вместо этого вы просто заключаете его в фигурные скобки (или двойные кавычки, но тогда вам придется экранировать вложенные):
spawn -noecho ssh -t XXXYYY {bash -c "cd /tmp;"}
это означает, что установленная вами переменная оболочки должна выглядеть примерно так
ssh_param = "-t ${scp_user}${_machine} {bash -c \"cd /tmp;\"}"
Написание всего этого в tcl/expect вместо оболочки, которая создает сценарии ожидания для выполнения, облегчит жизнь, поскольку вам не придется переключаться между различными стилями цитирования, беспокоиться о расширении параметров оболочки, вызывающем создание недопустимого tcl, как в этом примере, и т. д.
Я подумаю над тем, чтобы изменить его, спасибо большое за {bash -c \"cd /tmp;\"}
идею, это была именно она.
Взгляните на Обмен ключами SSH.