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

发布于 2024-11-01 01:27:44 字数 247 浏览 1 评论 0原文

使用 Python 的 subprocess 模块和 communicate() 方法时如何检索退出代码?

相关代码:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

我应该以另一种方式这样做吗?

How do I retrieve the exit code when using Python's subprocess module and the communicate() method?

Relevant code:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

Should I be doing this another way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

久而酒知 2024-11-08 01:27:44

Popen.communicate 将在完成时设置 returncode 属性(*)。这是相关的文档部分:

Popen.returncode 
  The child return code, set by poll() and wait() (and indirectly by communicate()). 
  A None value indicates that the process hasn’t terminated yet.

  A negative value -N indicates that the child was terminated by signal N (Unix only).

所以你可以这样做(我没有测试它,但它应该可以工作):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*)发生这种情况是因为它的实现方式:设置线程读取子流后,它只是调用 <代码>等待。

Popen.communicate will set the returncode attribute when it's done(*). Here's the relevant documentation section:

Popen.returncode 
  The child return code, set by poll() and wait() (and indirectly by communicate()). 
  A None value indicates that the process hasn’t terminated yet.

  A negative value -N indicates that the child was terminated by signal N (Unix only).

So you can just do (I didn't test it but it should work):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*) This happens because of the way it's implemented: after setting up threads to read the child's streams, it just calls wait.

旧城烟雨 2024-11-08 01:27:44

只是为了指出一个常见的误解,您应该尽可能避免 Popen。引用文档,

推荐的方法
调用子进程是
使用 run()功能
适用于所有用例
它可以处理。
对于更高级的
用例、底层
Popen 接口
可以直接使用。

如果您只想运行子流程并等待其完成,则只需使用 subprocess.run 或其旧同级 subprocess.call编写一行代码即可subprocess.check_output,并且您不需要复制/粘贴和/或了解低层所需的communicatewait等方法的复杂性级别 Popen 对象。

import subprocess

proc = subprocess.run(
    [openRTSP] + opts.split(),
    capture_output=True,
    # avoid having to explicitly encode
    text=True)
data = proc.stdout
result = proc.returncode

如果您不想捕获进程的输出,可以将 capture_output=True 替换为 stdout=subprocess.DEVNULL (对于 stderr 也许类似)代码>);如果两者都没有,输出将简单地显示给用户,不受 Python 的控制。

另外,除非 opts 中的选项完全微不足道,否则通常将此处的常规字符串 split() 替换为 shlex.split() ,它了解如何处理带引号的字符串。

Just to point out a common misconception, you should avoid Popen always when you can. To quote the documentation,

The recommended approach
to invoking subprocesses is
to use the run() function
for all use cases
it can handle.
For more advanced
use cases, the underlying
Popen interface
can be used directly.

If you just want to run a subprocess and wait for it to finish, that's a single line of code with subprocess.run or its legacy siblings subprocess.call and subprocess.check_output, and you don't need to copy/paste and/or understand the intricacies of the communicate and wait etc methods required around the low-level Popen object.

import subprocess

proc = subprocess.run(
    [openRTSP] + opts.split(),
    capture_output=True,
    # avoid having to explicitly encode
    text=True)
data = proc.stdout
result = proc.returncode

If you don't want to capture the output from the process, maybe replace capture_output=True with stdout=subprocess.DEVNULL (and perhaps similarly for stderr); in the absence of either, the output will simply be displayed to the user, outside of Python's control.

Also, unless your options in opts are completely trivial, generally replace the regular string split() here with shlex.split() which understands how to cope with quoted strings.

愚人国度 2024-11-08 01:27:44

.poll() 将更新返回码。

另外,在调用

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

.poll() 后,对象中的返回码可作为 child.returncode 使用。

.poll() will update the return code.

Try

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

In addition, after .poll() is called the return code is available in the object as child.returncode.

清引 2024-11-08 01:27:44

您应该首先确保进程已完成运行,并且已使用 .wait 方法读出返回码。这将返回代码。如果您想稍后访问它,它将作为 .returncode 存储在 Popen 对象中。

You should first make sure that the process has completed running and the return code has been read out using the .wait method. This will return the code. If you want access to it later, it's stored as .returncode in the Popen object.

人心善变 2024-11-08 01:27:44

在调用 process.communicate() 后使用 process.wait()
例如:

import subprocess

process = subprocess.Popen(['ipconfig', '/all'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
exit_code = process.wait()
print(stdout, stderr, exit_code)

Use process.wait() after you call process.communicate().
For example:

import subprocess

process = subprocess.Popen(['ipconfig', '/all'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
exit_code = process.wait()
print(stdout, stderr, exit_code)
回忆躺在深渊里 2024-11-08 01:27:44

exitcode = data.wait()。如果子进程写入标准输出/错误,和/或从标准输入读取,并且没有对等进程,则子进程将被阻止。

exitcode = data.wait(). The child process will be blocked If it writes to standard output/error, and/or reads from standard input, and there are no peers.

ゝ杯具 2024-11-08 01:27:44

这对我有用。它还打印子进程返回的输出

child = subprocess.Popen(serial_script_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retValRunJobsSerialScript = 0
    for line in child.stdout.readlines():
        child.wait()
        print line           
    retValRunJobsSerialScript= child.returncode

This worked for me. It also prints the output returned by the child process

child = subprocess.Popen(serial_script_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retValRunJobsSerialScript = 0
    for line in child.stdout.readlines():
        child.wait()
        print line           
    retValRunJobsSerialScript= child.returncode
太傻旳人生 2024-11-08 01:27:44

请看评论。

代码:

import subprocess


class MyLibrary(object):

    def execute(self, cmd):
        return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True,)
      
    def list(self):
        command = ["ping", "google.com"]
        sp = self.execute(command)
        status = sp.wait()  # will wait for sp to finish
        out, err = sp.communicate()
        print(out)
        return status # 0 is success else error


test = MyLibrary()

print(test.list())

输出:

C:\Users\shita\Documents\Tech\Python>python t5.py

Pinging google.com [142.250.64.78] with 32 bytes of data:
Reply from 142.250.64.78: bytes=32 time=108ms TTL=116
Reply from 142.250.64.78: bytes=32 time=224ms TTL=116
Reply from 142.250.64.78: bytes=32 time=84ms TTL=116
Reply from 142.250.64.78: bytes=32 time=139ms TTL=116

Ping statistics for 142.250.64.78:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 84ms, Maximum = 224ms, Average = 138ms

0

Please see the comments.

Code:

import subprocess


class MyLibrary(object):

    def execute(self, cmd):
        return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True,)
      
    def list(self):
        command = ["ping", "google.com"]
        sp = self.execute(command)
        status = sp.wait()  # will wait for sp to finish
        out, err = sp.communicate()
        print(out)
        return status # 0 is success else error


test = MyLibrary()

print(test.list())

Output:

C:\Users\shita\Documents\Tech\Python>python t5.py

Pinging google.com [142.250.64.78] with 32 bytes of data:
Reply from 142.250.64.78: bytes=32 time=108ms TTL=116
Reply from 142.250.64.78: bytes=32 time=224ms TTL=116
Reply from 142.250.64.78: bytes=32 time=84ms TTL=116
Reply from 142.250.64.78: bytes=32 time=139ms TTL=116

Ping statistics for 142.250.64.78:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 84ms, Maximum = 224ms, Average = 138ms

0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文