用python执行mysqldump并通过stdin设置密码

时间:2016-11-14 13:42:15

标签: python mysql subprocess

我想在python中执行mysqldump,并在mysqldump请求时提供密码。

在命令行中添加密码不是一个选项,必须通过stdin提供。

这是我到目前为止所做的:     command = [         'mysqldump的',         '-h',mysqlhost,         '-P',mysqlport,         '-u',mysqluser,         '-p',         MySQLdb的     ]

mysqlfile = mysqlpath + "/" + mysqldb + ".sql"
with open(mysqlfile, "w+") as file:
    p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=file)
    p.communicate(input=mysqlpass)
    p.wait()

但是当我执行代码时,终端挂起请求密码。

谢谢。

2 个答案:

答案 0 :(得分:2)

你可以使用pexpect。这是修改后的代码,因为我必须对其进行测试,但您明白了这一点:

import pexpect

command2 = 'mysqldump -h localhost -u root -p xyzzy'

mysqlfile = "/tmp/foo.sql"
with open(mysqlfile, "w+") as file:
    p = pexpect.spawn(command2)
    p.expect("Enter password: ")
    p.sendline("foobar")
    q = p.read()
    p.wait()
    file.write(q)

这里“foobar”是我的数据库密码。

哈努哈利

答案 1 :(得分:0)

对我来说,接受的答案并没有解决问题。据推测它与我使用的python版本有关,它是3.5。

我遇到的困难:

  1. p.read()阻止了这个过程(我总是在某个时候杀死脚本)
  2. David Rojo的 chunk -approach没有阻止,但是.read(1024)返回了整数,其中字符串位于file.write(...)所需的位置。我假设这与在Python 2和3中处理unicode的方式有所不同,因为将参数encoding='utf-8'添加到pexpect.spawn()给了我正确的结果。然而,那时我不得不调整文件的写作,s.t。它也支持unicode。
  3. for chunk in p.read(1024):方法的另一个问题是,我在mysqldump完成将转储写入stdout之前经历了读取完成。我想在这种情况下,mysqldump太慢而无法提供。我改变了我的解决方案,s.t。它等待EOF。
  4. 注意:我刚开始学习python几天前,如果我的假设或结论错误或误导,请纠正我。

    代码示例

    下面的脚本是我调用mysqldump并在mysqldump请求时提供密码的最小工作示例:

    #!/usr/bin/env python3
    import pexpect
    import io
    
    cmd = 'mysqldump -u MYSQL_USER -p DATABASES(S)'
    sqlfile = "/home/user/test-database-dump.sql"
    password = 'secret'
    
    with io.open(sqlfile, 'w', encoding="utf-8") as file:
        print('Calling mysqldump...')
        p = pexpect.spawn(cmd,encoding='utf-8')
        p.expect("Enter password: ")
    
        # Send password to mysqldump
        p.sendline(password)
    
        # Capture the dump
        print('Reading dump from process and writing it to file...')
        while not p.eof():
            chunk = p.readline()
            file.write(chunk)
        print('Finished.')
    
        p.close()
        print(p.exitstatus, p.signalstatus)