在写命令中保留颜色

时间:2015-08-21 12:21:31

标签: python linux

我正在使用write命令向朋友发送消息,我制作了一个简单的脚本,将我们提供的文本转换为ASCII艺术,如下所示:

ascii.py

import pyfiglet
from termcolor import cprint
import sys,random
f,t = '',''
fonts = list(pyfiglet.FigletFont.getFonts())
if sys.argv[-1] in fonts:
    f = sys.argv[-1]
    t = sys.argv[1:-1]
else:
    f = random.choice(fonts)
    t = sys.argv[1:]
cprint(pyfiglet.figlet_format(' '.join(t),str(f)),'red','on_blue',['bold'])
print(t)

然后我使用以下命令发送消息:

python ascii.py hi graffiti | write neo

当我运行不带管道的命令,即python ascii.py hi graffiti时,我得到以下输出:

enter image description here

但是当我运行python ascii.py hi graffiti | write neo时,颜色没有显示,而是显示了一些额外的字符,如下所示:

enter image description here

那么如何保留颜色以便它们到达另一端的人?

2 个答案:

答案 0 :(得分:2)

Python并没有删除颜色;他们在那里: 这些开始一些格式化

^[[1m^[[44m^[[31m

这样就结束了格式化

^[[0m
例如,在命令行上尝试这个

$ printf '\e[1;31mHello, World!\e[0m\n'

您将以红色显示文本,但不会显示格式字符。这是因为您的终端已解释了这些字符。

如果您这样做,您将看到格式化字符仍然存在。这是因为当终端从写入获取数据时,它不会解释转义序列。

$ printf '\e[1;31mHello, World!\e[0m\n' | write neo

发生的事情是逃脱序列' \ e [1; 31m'和' \ e [0m'正被转换为相关的字节值。您可以通过执行数据的hexdump来看到这一点

$ printf '\e[1;31mHello, World!\e[0m\n' | hexdump
0000000 5b1b 3b31 3133 486d 6c65 6f6c 202c 6f57
0000010 6c72 2164 5b1b 6d30 000a               
0000019
$ printf '\\e[1;31mHello, World!\\e[0m\n' | hexdump
0000000 655c 315b 333b 6d31 6548 6c6c 2c6f 5720
0000010 726f 646c 5c21 5b65 6d30 000a          
000001b

看到开始和结束字节有什么不同? Write正在接收格式化字节,但打印出相关的转义序列。

我不确切地知道为什么写不解释客户端的转义字符,但它可能是由于安全性(这些转义序列不仅可以更改字体)

如果你想要漂亮的颜色,你将无法使用

答案 1 :(得分:1)

好的,我运行了一个小测试,似乎问题是write - 命令必须做一些似乎不可参数化的恶作剧。

我写了这个小python脚本,在我的mac上将写入另一个终端(由write选择的同一个终端),它将为输出着色:

with open('/dev/ttys009', 'wb') as outf:
    outf.write('\x1b[35mfoobar\x1b[30m\n')

所以我猜你必须自己重新创建write,查看给定用户的/dev/tty*,然后打开该文件并写入。