期望脚本带有可选的ssh-agent passphrase提示符?

时间:2016-03-04 13:25:06

标签: ssh expect ssh-agent

我希望在 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':,第一个期望规则与之愉快匹配,并正确发送SSH密码。
  • ssh-agent 目前处于有效状态。在这种情况下,生成的 ssh 进程会静默建立端口转发,不需要或提示输入SSH密码。

我正在努力让这两个场景在我的期望脚本中运行。特别是,我不知道如何修改脚本,以便&#34;沉默&#34; active-ssh-agent是预期的&#34;因此,expect脚本可以继续启动数据库转储。

尝试期待多项内容方法(在?!?!?!?评论位置上方)尝试:

  • 期待换行,
  • 期待我的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

但是solutinos似乎会导致代码重复:每个条件提示都意味着复制并粘贴脚本的其余部分,这使得脚本可以通过每个ssh语句的嵌套条件提示快速复杂化。

ssh 由于活动的ssh-agent而没有提示输入密码/密码的情况下,如何让期望正常工作?

1 个答案:

答案 0 :(得分: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命令并与之交互。