【发布时间】:2016-03-04 13:25:06
【问题描述】:
我想在expect 的帮助下自动进行数据库备份:首先,脚本使用ssh 建立从远程数据库端口到我的本地计算机的转发端口。然后我使用数据库实用程序转储所有数据库。
因此,我在 bash 脚本中有以下 expect 脚本:
#!/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':,第一个 expect 规则很匹配,并正确发送 SSH 密码。 - 或 ssh-agent 当前处于活动状态。在这种情况下,生成的 ssh 进程会静默建立端口转发,不需要或提示输入 SSH 密码。
我正在努力让这两种情况都在我的期望脚本中工作。特别是,我不知道如何修改脚本以使“静默”的 active-ssh-agent 成为“预期”,因此预期脚本可以继续启动数据库转储。
我尝试了 expect multiple things 方法(在上面的?!?!?!? 评论位置):
- 期待换行,
- 期待我的 shell 提示,
- 期待
eof。
但没有一个有效。我在 StackExchange 周围发现了类似的问题和建议的解决方案: * How to use expect with optional prompts? * https://superuser.com/q/412259/137881 * TCL / Expect Scripting - Using a conditional statement to attempt a secondary login password
但这些解决方案似乎会导致代码重复:每个条件提示都意味着复制和粘贴脚本的其余部分,这使得脚本很快就会与每个 ssh 语句的嵌套条件提示变得复杂。
在 ssh 由于活动的 ssh 代理而没有提示输入密码短语/密码的情况下,如何期望正常工作?
【问题讨论】: