为啥在 python 脚本完成之前不执行打印作业?
Posted
技术标签:
【中文标题】为啥在 python 脚本完成之前不执行打印作业?【英文标题】:Why is the print job not executed until the python script has finished?为什么在 python 脚本完成之前不执行打印作业? 【发布时间】:2018-09-12 07:24:22 【问题描述】:据我了解,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 秒后打印(脚本结束时)。
关于执行环境:
os:ubuntu 18.04(也出现在 raspbian 上) python:3.6.5 打印机:通过 CUPS 的网络打印机(通过 USB 连接时也会出现)解决方案:
从用户 elias 的回答的 cmets 中可以看出,该行为是由缓冲引起的。
关闭stdin解决了问题。
lpr.stdin.close()
【问题讨论】:
【参考方案1】:我相信,如果您不在 Popen
调用中指定 stdout
,它将与父进程共享相同的内容,您的程序可能拥有其输出。
尝试添加stdout=subprocess.DEVNULL
(或stdout=subprocess.PIPE
,以防您想要捕获该输出)。
来自the docs:
stdin、stdout 和 stderr 分别指定执行程序的标准输入、标准输出和标准错误文件句柄。有效值为 PIPE、DEVNULL、现有文件描述符(正整数)、现有文件对象和无。 PIPE 表示应该创建一个通往子级的新管道。 DEVNULL 表示将使用特殊文件 os.devnull。默认设置为None,不会发生重定向;子文件句柄将从父文件继承。
【讨论】:
感谢您的快速回复。我添加了参数,但我不确定它是否解决了问题。按下按钮后似乎立即添加了打印作业,但未直接执行。也许这是 Ubuntu 的特性? 嗯,它可能是......如果你仍然想确保它会在后台运行,你也可以试试close_fds=True
(看到这个:***.com/a/34459371/149872)
@AFoeee 如果您在 shell 脚本而不是 python 脚本中运行命令,也会发生同样的事情吗?类似:echo -e "Username: testuser\nPassword: p4ssw0rd" | /usr/bin/lpr &
如果你得到相同的行为,那么问题肯定与python/urwid无关。
嗯,有趣!也许是因为缓冲?您可以在写入标准输入后尝试刷新它,例如 lpr.stdin.flush()
或者甚至关闭它 lpr.stdin.flush()
?以上是关于为啥在 python 脚本完成之前不执行打印作业?的主要内容,如果未能解决你的问题,请参考以下文章