根据我的理解,subprocess.Popen()应该创建一个新的过程,而不是阻止主要过程。
但是,以下脚本在完成之前不会打印。
按下按钮后似乎添加了打印作业,但由于某种原因未直接执行。 (至少Ubuntu显示添加的打印作业。)
为什么会出现这种情况?
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
lpr = subprocess.Popen("/usr/bin/lpr", # on raspbian: /usr/bin/lp
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL, # proposed by user elias
close_fds=True) # proposed by user elias
output = "Username: testuser\n".encode() \
+ "Password: p4ssw0rd\n".encode()
lpr.stdin.write(output)
while True:
pass
即使在使用ctrl-c退出之后,上面的脚本也不会打印任何内容。 (打印作业似乎留在队列中。)
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
import time
lpr = subprocess.Popen("/usr/bin/lpr", # on raspbian: /usr/bin/lp
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL, # proposed by user elias
close_fds=True) # proposed by user elias
output = "Username: testuser\n".encode() \
+ "Password: p4ssw0rd\n".encode()
lpr.stdin.write(output)
time.sleep(20)
这将在20秒后打印(脚本结束时)。
关于执行环境:
解:
从用户elias的回答中可以看出,行为是由缓冲引起的。
关闭stdin解决了这个问题。
lpr.stdin.close()
我相信如果你没有在stdout
调用中指定Popen
,它将与父进程共享相同的内容,即你的程序可能拥有的输出。
尝试添加stdout=subprocess.DEVNULL
(或stdout=subprocess.PIPE
,以防您想捕获该输出)。
来自the docs:
stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL,现有文件描述符(正整数),现有文件对象和无。 PIPE表示应该创建一个新的子管道。 DEVNULL表示将使用特殊文件os.devnull。使用默认设置None,不会发生重定向;子项的文件句柄将从父项继承。