[英]Getting pv output with subprocess
I am writing a script to automate database imports in MySQL. 我正在编写一个脚本来自动在MySQL中导入数据库。 I'm trying to write code that displays the output of
pv
as the database is imported: 我正在尝试编写代码,以在导入数据库时显示
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 is based on the code in this question , but it is not working for me. 这是基于此问题中的代码,但对我不起作用。 The
hello
never even gets printed, even if I comment out the other lines in the for loop - for line in pv.stderr
is blocking and I don't know why. 该
hello
甚至从来没有被印刷,即使我注释掉其他线路中的for循环- for line in pv.stderr
挡住,我不知道为什么。 It never unblocks, so even once the process has completed, the program is still stuck - I have to kill it. 它永远不会畅通无阻,因此即使该过程完成了,该程序仍然会卡住-我必须将其杀死。
What am I doing wrong that is causing for line in pv.stderr
to block? 我做错了什么导致
for line in pv.stderr
中的行阻塞?
When shell=True , args[0]
is the command to be executed and args[1:]
are arguments passed to sh
. 当shell = True时 ,
args[0]
是要执行的命令,而args[1:]
是传递给sh
参数。 You want -p
and restore_filepath
to be passed to pv
not sh
. 您希望将
-p
和restore_filepath
传递给pv
而不是sh
。 So use shell=False
. 因此,使用
shell=False
。 The same goes for your other subprocess.Popen
call. 您的其他
subprocess.Popen
调用也是如此。
Since with shell=True
, pv
is not receiving any arguments, so it is hanging because it was still waiting for a filename. 由于使用
shell=True
, pv
不接收任何参数,因此它挂起,因为它仍在等待文件名。 So again, the solution is to use shell=False
. 同样,解决方案是使用
shell=False
。
Also note when replacing a shell pipeline , you should close stdout
on the first process to allow it to receive SIGPIPE if the second process exists. 还要注意,在替换外壳程序管道时 ,如果第二个进程存在,则应在第一个进程上关闭
stdout
,以使其能够接收SIGPIPE。 This allows some programs (those that handle SIGPIPE) to more gracefully exit if the pipeline is broken. 如果管道中断,这可以使某些程序(处理SIGPIPE的程序)更正常地退出。
pv = subprocess.Popen(
["pv", "-f", restore_filepath],
shell=False, # optional, since this is the default
bufsize=1,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True,
)
mysql = subprocess.Popen(
["mysql",
"-u{}".format(db_user),
"-p{}".format(db_pass),
db_name],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
stdin=pv.stdout,
)
pv.stdout.close() # Allow pv to receive a SIGPIPE if mysql exits.
for line in pv.stderr:
print("hello")
sys.stdout.write("\r" + line.rstrip("\n"))
sys.stdout.flush()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.