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

我正在编写一个以特定顺序使用一堆 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.



呼如林
浏览 172回答 1
1回答

绝地无双

双方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:&nbsp; &nbsp; &nbsp;print('The process raised an error:', err.decode())这里有些例子:使用Popen:import subprocess# first a command that works correctlyproc = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = proc.communicate()if not err:&nbsp; &nbsp; print('--No errors--\n', out.decode())else:&nbsp; &nbsp; print('--Error--\n', err.decode())# prints:--No errors--anaconda3DesktopDocumentsDownloads# next a command, which generates an error. The `-w` switch is invalidproc = subprocess.Popen(['ls', '-w'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = proc.communicate()if not err:&nbsp; &nbsp; print('--No errors--\n', out.decode())else:&nbsp; &nbsp; print('--Error--\n', err.decode())# prints:--Error--&nbsp;ls: option requires an argument -- 'w'Try 'ls --help' for more information.使用 check_callcheck_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&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Traceback (most recent call last)<ipython-input-25-3cd5107991a2> in <module>()----> 1 ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; stderr=subprocess.PIPE)~/anaconda3/lib/python3.6/subprocess.py in check_call(*popenargs, **kwargs)&nbsp; &nbsp; 289&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if cmd is None:&nbsp; &nbsp; 290&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmd = popenargs[0]--> 291&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;raise CalledProcessError(retcode, cmd)&nbsp; &nbsp; 292&nbsp; &nbsp; &nbsp;return 0&nbsp; &nbsp; 293CalledProcessError: Command '['ls', '-w']' returned non-zero exit status 2.要处理异常,请使用try/except块。try:&nbsp; &nbsp; ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; stderr=subprocess.PIPE)except subprocess.CalledProcessError as e:&nbsp; &nbsp; ret_code = e.returncode&nbsp; &nbsp; print('An error occurred.&nbsp; Error code:', ret_code)# prints:An error occurred.&nbsp; Error code: 2使用 check_outputcheck_output非常相似,check_call如果来自命令系统的返回码不是 0,它将引发 Python 异常。但是,如果返回码为 0,它将返回标准输出流中的输出。# just with the error process this timetry:&nbsp; &nbsp; ret_code = subprocess.check_output(['ls', '-w'], stdout=subprocess.PIPE,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; stderr=subprocess.PIPE)except subprocess.CalledProcessError as e:&nbsp; &nbsp; ret_code = e.returncode&nbsp; &nbsp; print('An error occurred.&nbsp; Error code:', ret_code)# prints:An error occurred.&nbsp; Error code: 2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python