Python中popen与mysql的问题

3

我是Python的新手,多年没用过Linux了,所以不确定出了什么问题。我试图使用Popen在Ubuntu上运行MySQL中的sql文件。

下面是相关代码:

command = ['mysql', '-uUSER', '-pPWD','-h192.168.1.132',  '--database=dbName', '<', './1477597236_foo.sql' ]
print("command is: "+subprocess.list2cmdline(command))

proc = subprocess.Popen(
    command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd='.'
)

这将产生与运行'mysql --help'相同的输出。 令我困惑的是,如果我获取由subprocess.list2cmdline输出的命令并直接运行它,则可以完美运行。 另外,如果我将''替换为'-e select * from foo',则可以运行。 因此,'<>'和文件导致了我的问题。 我知道是什么原因造成了问题,但到目前为止,我尝试过的所有方法都没有解决它。
2个回答

7
当命令行中存在重定向、管道或内置命令时,需要使用shell=True。然而,在像这样的简单情况下,shell=True是过度设计的。有一种更加简洁的方法可以避免使用shell=True,从而更好地控制输入文件。
  • 如果输入文件不存在,则在到达子进程之前就会抛出异常,更易于处理
  • 该进程在没有Shell的情况下运行:具有更好的可移植性和性能
代码如下:
command = ['mysql', '-uUSER', '-pPWD','-h192.168.1.132',  '--database=dbName' ]

with open('./1477597236_foo.sql') as input_file:
    proc = subprocess.Popen(
        command, stdin = input_file, stderr=subprocess.PIPE, stdout=subprocess.PIPE )
    output,error = proc.communicate()

我添加了下一行代码 communicate 的调用:因为标准输出和错误输出都被重定向,这是避免两个输出流之间死锁的唯一简单方法。


1
最后一个选项是完全不使用subprocess:https://dev59.com/AnRC5IYBdhLWcg3wOOT1 - mgilson
典型的我:只看到了细节问题,忽略了大局。不过我的回答涵盖了在命令、SQL或其他情况下需要输入重定向的情况。很好的观点。 - Jean-François Fabre

0

所以你需要在Popen调用中添加shell=True<是shell的一部分,如果没有该参数,你将无法使用shell功能。

proc = subprocess.Popen( command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd='.',shell=True )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接