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

Why is the print job not executed until the python script has finished?

根据我的理解,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 的回答评论中可以看出,该行为是由缓冲引起的。

问题已通过 closing stdin 解决。

lpr.stdin.close()

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

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

来自the docs

stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent.