Ожидать сценарий с необязательной парольной фразой ssh-agent?
Я хочу автоматизировать резервное копирование базы данных с помощью ожидаемого: во-первых, сценарий устанавливает перенаправленный порт с порта удаленной базы данных на мой локальный компьютер с помощью ssh. Затем я использую утилиту базы данных, чтобы сбросить все базы данных.
Поэтому внутри bash- скрипта есть следующий ожидаемый скрипт:
#!/bin/sh
expect <<- DONE
set timeout -1
# port-forward remote database port 3306 to local port 3307
spawn ssh -M -S /var/run/examplecom-mysql-socket -fnNT -L 3307:localhost:3306 someuser@example.com
expect {
# conditional prompt appears in case ssh-agent is not active
"*.ssh/id_rsa':*" {
send -- "$SSH_PASSPHRASE\r"
}
# ?!?!?!? What to expect here in case ssh-agent is active, therefore no password needed, and therefore no prompt appears?
}
# dump remote database by connecting to forwarded port
spawn mysqldump --all-databases --user=root --password --protocol=TCP --host=localhost --port=3307 --verbose --result-file=${DB_DUMP_FILE}
expect {
# prompt appears for database password
"*?asswor?:*" {
send -- "$PASSWORD_MYSQL_ROOT\r"
}
}
expect eof
DONE
Этот сценарий может выполняться в двух сценариях:
- Либо ssh-agent в данный момент не активен. В этом случае порожденный процесс SSH предложит
Enter passphrase for key '${HOME}/.ssh/id_rsa':
, которому первое правило ожидания успешно соответствует, и правильно отправляет SSH-фразу. - Или ssh-agent в данный момент активен. В этом случае порожденный процесс ssh молча устанавливает переадресацию портов и не требует или не запрашивает пароль SSH.
Я изо всех сил пытаюсь заставить оба сценария работать в моем ожидаемом сценарии. В частности, я не знаю, как изменить сценарий так, чтобы "молчащий" активный-ssh-agent был "ожидаемым", и поэтому ожидаемый сценарий мог продолжить запускать дамп базы данных.
Я пытался ожидать многоплановый подход (выше ?!?!?!?
местоположение комментария), попробовав:
- ожидая перевода строки,
- ожидая моего приглашения оболочки,
- ожидая
eof
,
Но никто не работал. Я нашел похожие проблемы и предложил решения вокруг StackExchange: * Как использовать ожидаемый с необязательными подсказками? * https://superuser.com/q/412259/137881 * TCL / Expect Scripting - использование условного оператора для попытки ввода вторичного пароля для входа
Но solutinos, кажется, вызывают дублирование кода: каждое условное приглашение означает копирование и вставку остальной части сценария, что заставляет сценарий быстро извиваться с вложенными условными запросами для каждого оператора ssh.
Как можно ожидать корректной работы в ситуациях, когда ssh не запрашивает пароль / пароль из-за активного ssh-agent?
1 ответ
Да, это смешно. Так как вы используете SSH -N
, вы не запускаете никакой процесс на удаленном хосте, а сессия ssh просто сидит там. Вам просто нужно поспать пару секунд и надеяться, что туннель будет установлен.
set timeout 2
spawn ssh -M -S /var/run/examplecom-mysql-socket -fnNT -L 3307:localhost:3306 someuser@example.com
expect {
# conditional prompt appears in case ssh-agent is not active
"*.ssh/id_rsa':*" { send -- "$SSH_PASSPHRASE\r" }
# wait until the timeout, then carry on with the rest of the script
timeout
}
set timeout -1
# ...
Или удалить -N
, тогда вы можете ожидать увидеть приглашение на удаленном хосте.
spawn ssh -M -S /var/run/examplecom-mysql-socket -fnT -L 3307:localhost:3306 someuser@example.com
# ..........................................^^^^
expect {
# conditional prompt appears in case ssh-agent is not active
"*.ssh/id_rsa':*" { send -- "$SSH_PASSPHRASE\r" }
# I assume your prompt ends with a dollar sign and a space
-re {\$ $}
}
Теперь вы можете создавать команду mysql и взаимодействовать с ней.