使用expect确认密码

时间:2013-12-11 04:07:16

标签: bash expect

我正在尝试做的是编写一个expect脚本来备份服务器上的所有数据库,然后创建一个加密的zip文件(我无法让我的tar / openssl命令在期望中正常运行)包含sql文件。

这只是一个了解期望的练习,而不是真正的备份解决方案。

我显然在这里缺乏一些理解。我想做的是:

  • 将所有数据库备份到文件(已完成)
  • 运行zip命令以创建加密的zip文件(完成... sorta)
  • 回复“输入密码:”
  • 然后回复确认“验证密码:”

    #!/usr/bin/expect -f
    exp_internal 1
    set backupdir "/mnt/db-backups/"
    set now [clock seconds]
    set date [clock format $now -format {%Y-%m-%d}]
    set filename $date
    
    append filename "_dbbackups.sql"
    
    exec mysqldump -u root --all-databases --events > $backupdir$filename
    
    spawn zip -e $backupdir$filename.enc.zip $backupdir$filename
    
    expect {
        "Enter password: " { send "monkey"
        exp_continue
        }
        "Verify password: " {send "monkey"
        exp_continue
        }
    }
    

输出

    $expect encrypt.sh 
    spawn zip -e /mnt/db-backups/2013-12-11_dbbackups.sql.enc.zip /mnt/db-backups/2013-12-11_dbbackups.sql
    parent: waiting for sync byte
    parent: telling child to go ahead
    parent: now unsynchronized from child
    spawn: returns {15733}

    expect: does "" (spawn_id exp6) match glob pattern "Enter password: "? no
    "Verify password: "? no
    Enter password: 
    expect: does "Enter password: " (spawn_id exp6) match glob pattern "Enter password: "? yes
    expect: set expect_out(0,string) "Enter password: "
    expect: set expect_out(spawn_id) "exp6"
    expect: set expect_out(buffer) "Enter password: "
    send: sending "monkey" to { exp6 }
    expect: continuing expect

    expect: does "" (spawn_id exp6) match glob pattern "Enter password: "? no
    "Verify password: "? no
    monkey
    expect: does "monkey" (spawn_id exp6) match glob pattern "Enter password: "? no
    "Verify password: "? no
    -- then I exited --

这是一个非常简单的剧本......但我正在吮吸它。

4 个答案:

答案 0 :(得分:2)

问题很简单:

你必须按回车键。所以只需更改命令

send "monkey"

send "monkey\r"

(两者都是)

答案 1 :(得分:0)

期待是一个非常难看和麻烦的解决方案。

对于mysqldump部分,请按照以下格式在~/.my.cnf中添加数据库连接信息和密码:

[client]
database=dbname
user=dbuser
password=dbpass
host=dbhost

如果您使用多个数据库,那么您必须为每个数据库创建一个文件,例如~/.my.cnf.dbname,并像这样调用mysqldump

mysqldump --defaults-file=~/.my.cnf.$dbname $dbname | gzip >"$target"

请务必对此文件执行chmod 600以使其尽可能安全。

使用openssl进行加密时,可以将密码放在命令行中,如下所示:

... | openssl des3 -pass pass:monkey >"$target"

您可以在gzip之后将其放在先前的命令中。当然,如果您想要更高的安全性,请使用其他密码而不是des3。此外,您可能希望使用file:pathname选项代替在命令行上传递密码,而不是从文件的第一行获取密码。

答案 2 :(得分:0)

DRY:

spawn zip -e $backupdir$filename.enc.zip $backupdir$filename
expect {
    "* password: " {
        send "monkey\r"
        exp_continue
    }
    eof
}

答案 3 :(得分:0)

  

[...]写一个期望脚本[...]

不是我怎么做的。

  zip -P password [...]

对Zip版本(“zip -v”)一无所知,很难说 如果你只是没看文档(“zip -h2”,“man zip”)。 将密码放入脚本是一个足够的安全隐患 “-P”没有记录,直到Zip 3.0(当开发人员累了 回答我怎么做的问题。但是把密码放进去 脚本曾经几乎不比将密码放入脚本更糟糕 两次。