【发布时间】:2009-03-06 17:58:49
【问题描述】:
您好。
我编写了一个小 Python 脚本,在子进程中调用 MySQL。 [是的,我知道正确的方法是使用 MySQLdb,但在 OS X Leopard 下编译它很痛苦,如果我想在不同架构的计算机上使用该脚本,可能会更痛苦。] 子进程技术有效,前提是我在启动进程的命令中提供密码;但是,这意味着机器上的其他用户可以看到密码。
我写的原代码可以看here。
下面的这个变体非常相似,虽然我会省略测试例程以使其更短:
#!/usr/bin/env python
from subprocess import Popen, PIPE
# Set the command you need to connect to your database
mysql_cmd_line = "/Applications/MAMP/Library/bin/mysql -u root -p"
mysql_password = "root"
def RunSqlCommand(sql_statement, database=None):
"""Pass in the SQL statement that you would like executed.
Optionally, specify a database to operate on. Returns the result."""
command_list = mysql_cmd_line.split()
if database:
command_list.append(database)
# Run mysql in a subprocess
process = Popen(command_list, stdin=PIPE, stdout=PIPE,
stderr=PIPE, close_fds=True)
#print "Asking for output"
#needs_pw = process.stdout.readline()
#print "Got: " + needs_pw
# pass it in the password
process.stdin.write(mysql_password + "\n")
# pass it our commands, and get the results
#(stdout, stderr) = process.communicate( mysql_password + "\n" + sql_statement)
(stdout, stderr) = process.communicate( sql_statement )
return stdout
我怀疑 MySQL 密码提示实际上不在 stdout(或 stderr)上,尽管我不知道这是怎么回事,或者这是否意味着我可以捕获它。
在提供密码之前,我确实尝试过先读取输出,但它不起作用。我也试过传递密码
同样,如果我在命令行上提供密码(因此在“Popen”和“communicate”函数之间没有代码)我的包装函数可以工作。
两个新想法,几个月后:
使用pexpect 可以让我提供密码。它模拟一个 tty 并获取所有输出,即使是绕过 stdout 和 stderr 的输出。
有一个名为 MySQL Connector/Python 的项目处于早期 alpha 阶段,它将允许提供一个纯 Python 库来访问 MySQL,而无需您编译任何 C 代码。
【问题讨论】:
-
在网上一些实验和进一步搜索之间,我确定mysql的客户端在读取密码时不使用stdin,而是直接访问tty。因此,再多的重定向标准输入都不起作用。
-
@deemer - 我以为是这样的。
标签: python mysql subprocess