Python 子进程——如何忽略退出代码警告?
Posted
技术标签:
【中文标题】Python 子进程——如何忽略退出代码警告?【英文标题】:Python subprocess — how to ignore exit code warnings? 【发布时间】:2021-04-06 07:53:28 【问题描述】:我正在尝试通过默认程序显示最终的 results.txt 文件。我试过裸Popen()
没有run()
并得到相同的效果。目标文件正在打开(对我来说是查看模式),但退出后我收到:
警告:程序返回非零退出代码 #256
有什么方法可以忽略它并阻止我的程序显示此类警告?我不关心它,因为它是程序做的最后一件事,所以我不希望人们每次都浪费时间点击 Enter...
代码如下:
from subprocess import run, Popen
if filepath[len(filepath)-1] != '/':
try:
results = run(Popen(['start', 'results.txt'], shell=True), stdout=None, shell=True, check=False)
except TypeError:
pass
else:
try:
results = run(Popen(['open', 'results.txt']), stdout=None, check=False)
except TypeError:
pass
except FileNotFoundError:
try:
results = run(Popen(['see', 'results.txt']), stdout=None, check=False)
except TypeError:
pass
except FileNotFoundError:
pass
【问题讨论】:
什么 - 你将Popen
对象传递给 run
?这不是你使用这些东西的方式。
我已经尝试使用裸Popen
,正如我在帖子中已经提到的那样。这是有人向我求婚但没有成功的方式,这没关系,因为两种方式都行不通。我很欣赏run
或Popen
的解决方案,我不挑剔
首先是os.system()
,它允许像这样运行cmd命令:例如os.system('open results.txt')
。您也可以使用 python 打开文件,例如:with open('results.txt') as file:
或者如果您想以可视方式打开:os.startfile(r'path\to\file.extension')
可能还有其他内置方法来做您想做的更简单的事情
run
需要一个命令来运行,而不是一个 Popen
对象(它代表一个已经启动的进程)。
@Matiiss 我想以可视方式打开它们,但您的解决方案无法正常工作。 os.startfile(filepath + 'results.txt') AttributeError: module 'os' has no attribute 'startfile'
【参考方案1】:
您的直接错误是您将subprocess.run
与subprocess.Popen
混合在一起。正确的语法是
y = subprocess.Popen(['command', 'argument'])
或
x = subprocess.run(['command', 'argument'])
但你错误地将它们有效地组合成
x = subprocess.run(subprocess.Popen(['command', 'argument']), shell=True)
shell=True
本身就是一个单独的错误(尽管它在 Windows 上会奇怪地工作)。
发生的情况是Popen
运行成功,但随后您尝试在结果上运行run
,这当然不是一个有效的命令。
在这种情况下,您希望subprocess.run()
而不是subprocess.Popen
;后者用于在 run
无法提供足够灵活性的情况下(例如当您需要子进程与 Python 程序作为独立进程并行运行时)手动连接您自己的低级功能。
对于类 Unix 系统,您的方法似乎存在模糊的缺陷;你可能想运行xdg-open
(如果它可用),否则运行os.environ["PAGER"]
的值(如果它已定义),否则回退到less
,否则尝试more
。一些古老的系统也有一个默认的寻呼机,叫做pg
。
您肯定会想要添加check=True
,以确保在找不到命令时您的命令正确失败,这与您所要求的截然相反。使用这个关键字参数,Python 会检查命令是否有效,如果没有,将引发异常。 (如果没有它,通常会默默地忽略失败。)你 should never catch every possible exception; 只捕获你真正知道如何处理的人。
【讨论】:
好的,我很感谢您的回答,但是由于我已经在没有subprocess
模块的情况下使用了该程序(正如您在我自己的回答中看到的那样)我有一个关于该段落的问题关于类 Unix 操作系统。这是否意味着 Linux 的 os.system(see filename)
和 MacOS 的 os.system(open filename)
不够用或者没问题?
你可能在任何似乎工作的地方都可以使用os.system()
(如果你感觉特别有害,可以在导入时尝试这个),但实际上,你的程序对它和你来说会更糟可能会发现您与subprocess
有更好的界面。您仍然需要对其他操作系统进行更改(program
vs program.exe
vs Windows 下一般不可用的有用软件)。有趣的是,我会推荐 subprocess.Popen()
与 PIPE args 和某种形式的 .communicate(my_input)
而非其他用途。【参考方案2】:
好的,我通过不同的方法实现了我的目标。我不需要处理这种异常,我在没有子流程模块的情况下完成了。
问题结束,这是最终代码(看起来更好):
from os import system
from platform import system as sysname
if sysname() == 'Windows':
system('start results.txt')
elif sysname() == 'Linux':
system('see results.txt')
elif sysname() == 'Darwin':
system('open results.txt')
else:
pass
【讨论】:
os.system()
的文档明确建议您改用subprocess
。以上是关于Python 子进程——如何忽略退出代码警告?的主要内容,如果未能解决你的问题,请参考以下文章