为了账号安全,请及时绑定邮箱和手机立即绑定

如何检查子进程中的 Popen 是否引发错误

如何检查子进程中的 Popen 是否引发错误

呼如林 2021-10-12 10:17:29
我正在编写一个以特定顺序使用一堆 bash 调用的管道。如何判断我的命令是否引发错误?例如,我正在运行一个带有子进程的 Java 程序,当这个进程出错时它不会警告我或退出。subprocess我的process对象中或对象中是否有具有此实用程序的东西?process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)process.wait()当我尝试来自Python的建议:“subprocess.Popen”检查成功和错误时,我收到以下错误:In [6]: subprocess.check_call(process)---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-6-f8f8752a245f> in <module>----> 1 subprocess.check_call(process)~/anaconda/envs/µ_env/lib/python3.6/subprocess.py in check_call(*popenargs, **kwargs)    284     check_call(["ls", "-l"])    285     """--> 286     retcode = call(*popenargs, **kwargs)    287     if retcode:    288         cmd = kwargs.get("args")~/anaconda/envs/µ_env/lib/python3.6/subprocess.py in call(timeout, *popenargs, **kwargs)    265     retcode = call(["ls", "-l"])    266     """--> 267     with Popen(*popenargs, **kwargs) as p:    268         try:    269             return p.wait(timeout=timeout)~/anaconda/envs/µ_env/lib/python3.6/subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors)    707                                 c2pread, c2pwrite,    708                                 errread, errwrite,--> 709                                 restore_signals, start_new_session)    710         except:    711             # Cleanup if the child failed starting.
查看完整描述

1 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

双方check_call并check_output应传递命令的列表由指挥系统(即会被发送到相同的命令列表中运行Popen)。这两个都是阻塞调用,这意味着 Python 将等到它们完成运行更多代码。


UsingPopen将命令列表发送到命令系统,但不会阻止 Python 代码的进一步执行。您可以使用对象的.poll方法检查进程Popen,或者您可以进行阻塞调用,使用.communicate它将返回标准输出和标准错误流的元组。


假设你想要执行命令的结果,并且命令会正确地向错误流报告错误,你可以使用:


process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out, err = process.communicate()


if err:

     print('The process raised an error:', err.decode())

这里有些例子:

使用Popen:

import subprocess


# first a command that works correctly

proc = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out, err = proc.communicate()

if not err:

    print('--No errors--\n', out.decode())

else:

    print('--Error--\n', err.decode())


# prints:

--No errors--

anaconda3

Desktop

Documents

Downloads


# next a command, which generates an error. The `-w` switch is invalid

proc = subprocess.Popen(['ls', '-w'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out, err = proc.communicate()

if not err:

    print('--No errors--\n', out.decode())

else:

    print('--Error--\n', err.decode())


# prints:

--Error--

 ls: option requires an argument -- 'w'

Try 'ls --help' for more information.

使用 check_call

check_call 如果来自命令系统的返回码不是 0,则会引发 Python 异常。


# first with a working command:

ret_code = subprocess.check_call(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

ret_code

# returns:

0


# and now with the command that generates an error:

ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)


# raises an exception:

---------------------------------------------------------------------------

CalledProcessError                        Traceback (most recent call last)

<ipython-input-25-3cd5107991a2> in <module>()

----> 1 ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE, 

        stderr=subprocess.PIPE)


~/anaconda3/lib/python3.6/subprocess.py in check_call(*popenargs, **kwargs)

    289         if cmd is None:

    290             cmd = popenargs[0]

--> 291         raise CalledProcessError(retcode, cmd)

    292     return 0

    293


CalledProcessError: Command '['ls', '-w']' returned non-zero exit status 2.

要处理异常,请使用try/except块。


try:

    ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE, 

        stderr=subprocess.PIPE)

except subprocess.CalledProcessError as e:

    ret_code = e.returncode

    print('An error occurred.  Error code:', ret_code)


# prints:

An error occurred.  Error code: 2

使用 check_output

check_output非常相似,check_call如果来自命令系统的返回码不是 0,它将引发 Python 异常。但是,如果返回码为 0,它将返回标准输出流中的输出。


# just with the error process this time

try:

    ret_code = subprocess.check_output(['ls', '-w'], stdout=subprocess.PIPE, 

        stderr=subprocess.PIPE)

except subprocess.CalledProcessError as e:

    ret_code = e.returncode

    print('An error occurred.  Error code:', ret_code)


# prints:

An error occurred.  Error code: 2


查看完整回答
反对 回复 2021-10-12
  • 1 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信