Python “subprocess.Popen” - 检查成功和错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25079140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"subprocess.Popen" - checking for success and errors
提问by Zingam
I want to check if a subprocess has finished execution successfully or failed. Currently I have come up with a solution but I am not sure if it is correct and reliable. Is it guaranteed that every process outputs its errors only to stderr respectfully to stdout:
我想检查一个子流程是否成功完成执行或失败。目前我已经提出了一个解决方案,但我不确定它是否正确和可靠。是否保证每个进程仅将其错误输出到 stderr 尊重stdout:
Note: I am not interested in just redirecting/printing out the output. That I know already how to do.
注意:我对重定向/打印输出不感兴趣。我已经知道该怎么做了。
pipe = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
if "" == pipe.stdout.readline():
print("Success")
self.isCommandExectutionSuccessful = True
if not "" == pipe.stderr.readline():
print("Error")
self.isCommandExectutionSuccessful = True
alternatively:
或者:
if "" == pipe.stdout.readline():
print("Success")
self.isCommandExectutionSuccessful = True
else:
print("Error")
self.isCommandExectutionSuccessful = False
and:
和:
if not "" == pipe.stderr.readline():
print("Success")
self.isCommandExectutionSuccessful = True
else:
print("Error")
self.isCommandExectutionSuccessful = False
采纳答案by elParaguayo
Do you need to do anything with the output of the process?
您需要对流程的输出做些什么吗?
The check_callmethod might be useful here. See the python docs here: https://docs.python.org/2/library/subprocess.html#subprocess.check_call
该check_call方法可能在这里有用。在此处查看 python 文档:https: //docs.python.org/2/library/subprocess.html#subprocess.check_call
You can then use this as follows:
然后,您可以按如下方式使用它:
try:
subprocess.check_call(command)
except subprocess.CalledProcessError:
# There was an error - command exited with non-zero code
However, this relies on commandreturning an exit code of 0 for succesful completion and a non-zero value for an error.
但是,这依赖于command返回退出代码 0 以表示成功完成和返回非零值表示错误。
If you need to capture the output as well, then the check_outputmethod may be more appropriate. It is still possible to redirect the standard error if you need this as well.
如果您还需要捕获输出,那么该check_output方法可能更合适。如果您也需要,仍然可以重定向标准错误。
try:
proc = subprocess.check_output(command, stderr=subprocess.STDOUT)
# do something with output
except subprocess.CalledProcessError:
# There was an error - command exited with non-zero code
See the docs here: https://docs.python.org/2/library/subprocess.html#subprocess.check_output
请参阅此处的文档:https: //docs.python.org/2/library/subprocess.html#subprocess.check_output
回答by vks
output,error=pipe.communicate()
This will wait for command to finish and give you output or error depending on the state of command.
这将等待命令完成并根据命令的状态为您提供输出或错误。
回答by Alexey Bureev
You can check return code of the process using check_call() method. In case if process returned non-zero value CalledProcessError will be raised.
您可以使用 check_call() 方法检查进程的返回代码。如果进程返回非零值 CalledProcessError 将被引发。
回答by Zingam
This is how I did it finally:
这就是我最终做到的:
# Call a system process
try:
# universal_newlines - makes manual decoding of subprocess.stdout unnecessary
output = subprocess.check_output(command,
stderr=subprocess.STDOUT,
universal_newlines=True)
# Print out command's standard output (elegant)
self.textEdit_CommandLineOutput.insertPlainText(output)
self.isCommandExecutionSuccessful = True
except subprocess.CalledProcessError as error:
self.isCommandExecutionSuccessful = False
errorMessage = ">>> Error while executing:\n"\
+ command\
+ "\n>>> Returned with error:\n"\
+ str(error.output)
self.textEdit_CommandLineOutput.append(errorMessage)
QMessageBox.critical(None,
"ERROR",
errorMessage)
print("Error: " + errorMessage)
except FileNotFoundError as error:
errorMessage = error.strerror
QMessageBox.critical(None,
"ERROR",
errorMessage)
print("Error: ", errorMessage)
I hope it will be useful to someone else.
我希望它对其他人有用。
回答by PJ_Finnegan
Complete solution with check on return code, stdout and stderr:
检查返回码、标准输出和标准错误的完整解决方案:
import subprocess as sp
# ok
pipe = sp.Popen( 'ls /bin', shell=True, stdout=sp.PIPE, stderr=sp.PIPE )
# res = tuple (stdout, stderr)
res = pipe.communicate()
print("retcode =", pipe.returncode)
print("res =", res)
print("stderr =", res[1])
for line in res[0].decode(encoding='utf-8').split('\n'):
print(line)
# with error
pipe = sp.Popen( 'ls /bing', shell=True, stdout=sp.PIPE, stderr=sp.PIPE )
res = pipe.communicate()
print("retcode =", pipe.returncode)
print("res =", res)
print("stderr =", res[1])
Prints:
印刷:
retcode = 0
res = (b'bash\nbunzip2\nbusybox\nbzcat\n...zmore\nznew\n', b'')
stderr = b''
bash
bunzip2
busybox
bzcat
...
zmore
znew
retcode = 2
res = (b'', b"ls: cannot access '/bing': No such file or directory\n")
stderr = b"ls: cannot access '/bing': No such file or directory\n"

