我想在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()
但是当我执行代码时,终端挂起请求密码。
谢谢。
答案 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。
我遇到的困难:
p.read()
阻止了这个过程(我总是在某个时候杀死脚本).read(1024)
返回了整数,其中字符串位于file.write(...)
所需的位置。我假设这与在Python 2和3中处理unicode的方式有所不同,因为将参数encoding='utf-8'
添加到pexpect.spawn()
给了我正确的结果。然而,那时我不得不调整文件的写作,s.t。它也支持unicode。for chunk in p.read(1024):
方法的另一个问题是,我在mysqldump完成将转储写入stdout之前经历了读取完成。我想在这种情况下,mysqldump太慢而无法提供。我改变了我的解决方案,s.t。它等待EOF。注意:我刚开始学习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)