Python 用意外的间距诅咒 Git 子进程输出

标签 python git curses

当我在 python-curses 屏幕中调用 git 时,我观察到一个奇怪的间距问题。我在下面的最小工作示例中做了什么,导致间距半开且不与屏幕侧面齐平?

最小工作示例:

import curses, subprocess

class MyApp(object):

    def __init__(self, stdscreen):
        self.screen = stdscreen
        self.screen.addstr("Loading..." + '\n')
        self.screen.refresh()

        url = 'http://github.com/octocat/Hello-World/'

        process = subprocess.Popen(['git', 'clone', url], stdout=subprocess.PIPE)

        self.screen.addstr("Press any key to continue.")

        self.screen.getch()

if __name__ == '__main__':
    curses.wrapper(MyApp)

输出:

Loading...
Press any key to continue.Cloning into 'Hello-World'...
                                                       warning: redirecting to https://github.com/octocat/Hello-World/
              remote: Enumerating objects: 13, done.
                                                    remote: Total 13 (delta 0), reused 0 (delta 0), pack-reused 13
Unpacking objects: 100% (13/13), done.3)

预期输出:

Loading...
Cloning into 'Hello-World'...
warning: redirecting to https://github.com/octocat/Hello-World/
remote: Enumerating objects: 13, done.
remote: Total 13 (delta 0), reused 0 (delta 0), pack-reused 13
Unpacking objects: 100% (13/13), done.3)
Press any key to continue.

最佳答案

git clone 将其信息性消息写入 stderr,而不是 stdout。

From the documentation(添加强调):

--verbose

Run verbosely. Does not affect the reporting of progress status to the standard error stream.

<小时/>

(以下代码由 Justapigeon 提供)

考虑到这一点更新了 MWE:

import curses, subprocess
import os, re

class MyApp(object):

    def __init__(self, stdscreen):
        self.screen = stdscreen
        self.screen.addstr("Loading..." + '\n')
        self.screen.refresh()

        url = 'http://github.com/octocat/Hello-World/'

        #process = subprocess.Popen(['git', 'clone', url], stdout=subprocess.PIPE)

        # additional code from: https://stackoverflow.com/a/39564562/6924364

        dloutput = subprocess.Popen(['git', 'clone', '--progress', url], stderr=subprocess.PIPE, stdout=subprocess.PIPE)

        fd = dloutput.stderr.fileno()
        gitmsg = [] 
        while True:
            lines = os.read(fd,1000).decode('utf-8')
            lines = re.split('\n|\r', lines)
            for l in lines:
                self.screen.erase()
                for g in gitmsg:
                    self.screen.addstr(g + '\n')
                if l != '':
                    self.screen.addstr(str(l) + '\n')
                    self.screen.refresh()
                if 'Cloning' in l:
                    gitmsg.append(l)
                if 'done' in l:
                    gitmsg.append(l)
            if len(lines) == 1:
                break

        self.screen.addstr("Press any key to continue.")

        self.screen.getch()

if __name__ == '__main__':
    curses.wrapper(MyApp)

关于Python 用意外的间距诅咒 Git 子进程输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59804468/

相关文章:

git - 在 git 中签署标签有什么意义?

git - GitHub Enterprise 是否支持浅克隆?

python - 当 bkgd 字符为curses.ACS_CKBOARD 时,文本显示损坏

python - 切换 py2app 独立模式?

python - 在 theano 中定义表达式

python - Dicom 变形图像配准

git rebase -i --retain-empty-commits

c - 如何安装 pdcurses

python - 多处理在Python中挂起诅咒

python - 加入列并在行中 reshape