我正在编写一个脚本来自动化MySQL中的数据库导入。我正在尝试编写代码,以在导入数据库时显示pv
的输出:
pv = subprocess.Popen(
["pv", "-f", restore_filepath],
bufsize=1,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True,
shell=True,
)
subprocess.Popen(
[
"mysql",
"-u{}".format(db_user),
"-p{}".format(db_pass),
db_name,
],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
stdin=pv.stdout,
)
for line in pv.stderr:
print("hello")
sys.stdout.write("\r" + line.rstrip("\n"))
sys.stdout.flush()
这基于this question中的代码,但对我不起作用。即使我注释掉for循环中的其他行,hello
甚至都不会被打印-for line in pv.stderr
处于阻塞状态,我也不知道为什么。它永远不会畅通无阻,因此即使该过程完成,该程序仍然会卡住-我必须将其杀死。
我在做什么导致for line in pv.stderr
被阻止?
答案 0 :(得分:2)
When shell=True,val castedArgs: Array<Any> = tokens.map { it.type.cast(it) }.toTypedArray()
是要执行的命令,args[0]
是传递给args[1:]
的参数。您希望将sh
和-p
传递给restore_filepath
而不是pv
。因此,请使用sh
。您的其他shell=False
通话也是如此。
由于subprocess.Popen
的使用,shell=True
没有收到任何参数,因此它挂起是因为它仍在等待文件名。同样,解决方案是使用pv
。
还请注意,当replacing a shell pipeline时,如果第二个进程存在,则应在第一个进程上关闭shell=False
,以使其接收SIGPIPE。如果管道中断,这可以使某些程序(处理SIGPIPE的程序)更正常地退出。
stdout