python-3.x 筛选从子进程.check_call接收的输出

7kqas0il  于 2023-08-08  发布在  Python
关注(0)|答案(1)|浏览(104)

需要向下面的Python 3脚本添加什么特定语法,以便脚本过滤每一行结果并评估是否有任何输出行包含特定的子字符串?
下面是成功运行git clone命令的代码:

newpath="C:\\path\\to\\destination\\"
cloneCommand='git clone https://github.com/someuser/somerepo.git'
proc = subprocess.check_call(cloneCommand, stdout=subprocess.PIPE, shell=True, cwd=newpath, timeout=None)

字符串
上面的代码成功克隆了预期的存储库。但问题是没有错误处理。
我希望脚本能够在输出的每一行中监听单词deltasdone,以便在输出中打印以下行时指示成功:

Resolving deltas: 100% (164/164), done.


subprocess.Popen(...)允许我们过滤流输出的每一行。但是,当我们运行像git clone这样的远程命令时,subprocess.Popen(...)不起作用,因为subprocess.Popen(...)不会等待接收像git clone这样的远程调用的返回。
我们需要使用什么语法来过滤subprocess.check_call(...)调用的输出?

tvz2xvvm

tvz2xvvm1#

一个小脚本,我们可以执行它来测试Popen代码。它在退出之前生成一些STDOUT和STDERR,然后选择一个我们选择的代码,可选地带有一些延迟:

from sys import stdout, stderr, exit, argv
from time import sleep

stdout.write('OUT 1\nOUT 2\nOUT 3\n')
sleep(2)
stderr.write('err 1\nerr 2\n')
exit(int(argv[1]))

字符串
演示如何使用Popen的脚本。这个脚本的参数将是我们要执行的外部命令。

import sys
from subprocess import Popen, PIPE

# A function that takes some subprocess command arguments (list, tuple,
# or string), runs that command, and returns a dict containing STDOUT,
# STDERR, PID, and exit code. Error handling is left to the caller.
def run_subprocess(cmd_args, shell = False):
    p = Popen(cmd_args, stdout = PIPE, stderr = PIPE, shell = shell)
    stdout, stderr = p.communicate()
    return dict(
        stdout = stdout.decode('utf-8').split('\n'),
        stderr = stderr.decode('utf-8').split('\n'),
        pid = p.pid,
        exit_code = p.returncode,
    )

# Run a command.    
cmd = sys.argv[1:]
d = run_subprocess(cmd)

# Inspect the returned dict.
for k, v in d.items():
    print('\n#', k)
    print(v)


如果第一个脚本被称为other_program.py,而这个脚本被称为demo.py,你可以沿着以下代码运行整个脚本:

python demo.py python other_program.py 0  # Exit with success.
python demo.py python other_program.py 1  # Exit with failure.
python demo.py python other_program.py X  # Exit with a Python error.


git clone的用法示例,如在注解中与OP讨论的:

$ python demo.py git clone --progress --verbose https://github.com/hindman/jump

# stdout
['']

# stderr
["Cloning into 'jump'...", 'POST git-upload-pack (165 bytes)', 'remote: Enumerating objects: 70, done.        ', 'remote: Total 70 (delta 0), reused 0 (delta 0), pack-reused 70        ', '']

# pid
7094

# exit_code
0

相关问题