首页 > 解决方案 > 彩色终端并排差异在python中被打破

问题描述

我正在尝试构建一个 python 应用程序以在 python 中快速生成颜色并排差异。我的问题是我可以从 linux CLI 并排生成,但是无论我尝试过什么命令修改,差异在 python 下都会失败(请参阅下面的尝试)。

如果我从 linux CLI(在 下)运行差异,这是正确的行为wsltty。请注意,我从以下位置获得相同的输出PuTTYcorrect_color_sidebyside_diffs

当我从 python 脚本运行差异时, 这是典型的不需要的行为......不正确的_color_sidebyside_diffs

问题:

下面的 python 脚本包含我试图使 python 渲染的并排差异工作的尝试......简而言之,我已经尝试了多次尝试Popen(),以及subprocess.run()os.system()......

# filename: test_ydiff.py
from subprocess import run, Popen, PIPE
import shlex, os, pydoc

TEST_01 = True
TEST_02 = True
TEST_03 = True
if TEST_01:
    cmd_01_input   = "diff -u f_01.txt f_02.txt"
    cmd_01_output  = "ydiff -s"
    proc_01_input  = Popen(shlex.split(cmd_01_input),
                                    stdout=PIPE)
    proc_01_output = Popen(shlex.split(cmd_01_output),
        stdin=proc_01_input.stdout, stdout=PIPE)
    stdout_str, stdin_str = proc_01_output.communicate()
    print(stdout_str.decode('utf-8'))

if TEST_02:
    cmd_02_shell    = "diff -u f_01.txt f_02.txt | ydiff -s"
    proc_02_shell   = Popen(cmd_02_shell, shell=True, stdout=PIPE)
    stdout_str, stdin_str = proc_02_shell.communicate()
    print(stdout_str.decode('utf-8'))

if TEST_03:
    run("/usr/bin/diff -u ./f_01.txt ./f_02.txt|/home/mpennington/venv/py37_u18/bin/ydiff -s")

第一个要区分的文本文件:

# filename: f_01.txt
!
interface Ethernet0/0
 ip address 10.0.0.1 255.255.255.0
 no ip proxy-arp
 no ip unreachables
 ip access-group FILTER_in in
!

要区分的第二个文本文件:

# filename: f_02.txt
!
interface Ethernet0/0
 ip address 10.0.0.1 255.255.255.0
 ip proxy-arp
 no ip unreachables
!

我在 Ubuntu 18 下运行 Python 3.7.6...我有ydiff==1.1(github: ydiff)

标签: pythonterminaldiff

解决方案


这是 tty 设置问题之一。果然快速查看ydiff.py显示它正在检查sys.stdout.isatty()(aka os.isatty(2)),这用于确定您的 stdout fd 是否通过管道传输到某个命令。然后,您可以决定去除颜色格式,这就是 ydiff 对您所做的。

"diff -u f_01.txt f_02.txt | ydiff -s "不会在调用期间通过管道传输到命令,os.system它会在任何命令期间传输,subprocess因为您正在使用stdout=PIPE.

例如,如果您将测试脚本的输出通过管道传输到less例如,您会发现该subprocess方法也将不起作用,因为您现在已经添加了一个管道到stdout您的测试,从而使ydiff.py有一个管道到less.

好吧,无聊的部分结束了: readingydiff.py的选项处理表明它有一个 --color 选项,它以这种方式解析。

if (opts.color == 'always' or
    (opts.color == 'auto' and sys.stdout.isatty())):
    markup_to_pager(stream, opts)
else:
    # pipe out stream untouched to make sure it is still a patch
    byte_output = (sys.stdout.buffer if hasattr(sys.stdout, 'buffer')
               else sys.stdout)
    for line in stream:
        byte_output.write(line)

因此,您可以将其添加到命令行中以使其工作。

if TEST_02:
    cmd_02_shell    = "diff -u f_01.txt f_02.txt | ydiff -s --color='always'"

好问题,因为我喜欢 ydiff.py 的输出

这里的小编辑:

不知道你是否意识到,但 ydiff 也非常适合显示 git diff。要在您的 repo 目录中尝试,只需执行此操作。接受一个可选文件进行比较。

$ ydiff -s [my_git_file] 

如果你问我,那就太酷了。


推荐阅读