为啥在 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 脚本完成之前不执行打印作业?的主要内容,如果未能解决你的问题,请参考以下文章

打印机有打印任务但不工作是为啥?

为啥 AWS Lambda 函数在回调函数执行之前完成?

查看脚本执行了多远

Python脚本在执行另一个脚本之前等待

为啥浏览器在执行 JavaScript 之前并不总是完成对前面 HTML 的渲染?

当我从 SQL Server 代理运行 Python 脚本时,为啥它会失败?