为什么在python脚本完成之前不执行打印作业?

时间:2018-09-12 07:24:23

标签: python printing process printers cups

据我所知,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 的答案注释中可以看出,该行为是由缓冲引起的。

通过关闭stdin解决了问题。

lpr.stdin.close()

1 个答案:

答案 0 :(得分:1)

我相信,如果您在stdout调用中未指定Popen,它将与您的程序可能拥有其输出的父进程共享相同的内容。

尝试添加stdout=subprocess.DEVNULL(或stdout=subprocess.PIPE,以防您想要捕获该输出)。

来自the docs

  

stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL,现有文件描述符(正整数),现有文件对象和无。 PIPE指示应创​​建到子级的新管道。 DEVNULL表示将使用特殊文件os.devnull。使用默认设置无,将不会发生重定向。子文件的句柄将从父文件继承。