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,正如我在帖子中已经提到的那样。这是有人向我求婚但没有成功的方式,这没关系,因为两种方式都行不通。我很欣赏runPopen 的解决方案,我不挑剔 首先是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.runsubprocess.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 子进程——如何忽略退出代码警告?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 子进程通信方法时如何获取退出代码?

Supervisor进程管理

使用supervisor进行进程管理

探究守护进程及其错误日志处理

Python 多进程 ValueArray应用记录

python多进程和多线程