如何使用子流程管道进行错误处理

时间:2019-01-16 18:21:37

标签: python-3.x error-handling subprocess

似乎我无法两次访问process.stdout。但是我不确定如何解决它。我正在尝试捕获由命令导致的任何git错误,并捕获任何有用的输出。

如果输出错误或不存在,我想了解一下,因此我不会最终尝试修改不存在或无意义的变量。

但是,似乎通过探测输出是否有错误,我失去了捕获有意义输出的能力。

是否有更好的方法可以满足这两种情况?

到目前为止,我已经尝试了两个排列。但是当我首先检查有效性时,我似乎无法访问输出以对其进行任何处理。但是,如果我尝试不进行验证就使用它,则会丢失错误处理。

def gitinfo(sha1, placeholder, repoDir = '/mnt/d/stash.projects/rea'):
    placeholders = {'hash':'%H', 'comment':'%s', 'time':'%cd', 'newline':'%n'}

    if placeholder not in placeholders:
        print('Error: function gitinfo is not programmed for paceholder: ' + placeholder)
        print('Please see source, or try \'hash\', \'comment\', \'time\', or \'newline\'.')
        return 'Good day.'

    format_option = '--format="' + str(placeholders[placeholder.lower()]) + '"'
    date_format = '%Y-%m-%d %H:%M:%S'
    date_option = '--date=format:\'' + date_format + '\''
    cmd = ['git', 'show', format_option, date_option, '-s', sha1]

    with subprocess.Popen(cmd, cwd=repoDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) as proc:

        if not proc.stdout.read():
            warn(proc.stderr.read())
            return 'Error retrieving ' + placeholder + ' in function gitinfo.'


        for line in proc.stdout:
            result = line.rstrip('\n')


    if placeholder.lower() == 'time':
        result = result.replace("'", "")

    return result

1 个答案:

答案 0 :(得分:1)

stdoutstderr不是字符串,而是流。想到它们的一种方法就像是一个水箱:将水倒入顶部的过程中,您可以在底部找到一个水龙头。 stdout.read()说:“打开水龙头,直到水箱里没有水为止。”-如果您没有在水龙头下放一个水桶(在这个类比中分配一个变量),水就没了。 ,并且再次从空的水箱中打开水龙头不会把它带回来。

如果需要多次访问流中的同一输出,则必须将其存储在变量中,然后每次都引用该变量。就您而言,您可以执行以下操作:

output = proc.stdout.read()
if not output:
    # your error handling here
for line in output.split("\n"):
    # do stuff with line here