我有一个python脚本,它管理任何应用程序的stdin,stdout和stderr,并允许优雅地插入readline。想想任何具有大量控制台输出的应用程序,但也接受来自stdin的命令。
无论如何,我的脚本使用这两个函数:
def blank_current_readline():
# Next line said to be reasonably portable for various Unixes
(rows,cols) = struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,'1234'))
text_len = len(readline.get_line_buffer())+2
# ANSI escape sequences (All VT100 except ESC[0G)
sys.stdout.write('\x1b[2K') # Clear current line
sys.stdout.write('\x1b[1A\x1b[2K'*(text_len/cols)) # Move cursor up and clear line
sys.stdout.write('\x1b[0G') # Move to start of line
def print_line(line):
global cmd_state
blank_current_readline()
print line,
sys.stdout.write(cmd_state["prompt"] + readline.get_line_buffer())
sys.stdout.flush()
处理stdout时,我调用print_line()。这会使用户输入的内容空白,打印该行,然后恢复用户的输入文本。这一切都是在没有用户注意到事情的情况下发生的。
当光标不在用户输入的任何输入的末尾时,会出现问题。当光标位于测试中间并打印一行时,光标将自动放置在输入的末尾。要解决这个问题,我想在print_line中执行类似的操作:
def print_line(line):
global cmd_state
cursorPos = getCurrentCursorPos() #Doesn't exist
blank_current_readline()
print line,
sys.stdout.write(cmd_state["prompt"] + readline.get_line_buffer())
sys.stdout.setCurrentCursorPos(cursorPos) #Doesn't exist
sys.stdout.flush()
编辑:尝试可视化我写的内容:
终端看起来像这样:
----------------------------------------------
| |
| |
| <scolling command output here> |
| |
| <scolling command output here> |
| |
|: <user inputted text here> |
----------------------------------------------
因此,当新日志通过时,输出文本会不断滚动。同时,用户当前正在编辑和编写一个新命令,一旦命中输入就会插入该命令。所以它看起来像python控制台,但总是附加输出。
答案 0 :(得分:4)
我可以建议Python curses吗?
以下是Basic how-to
curses模块提供了curses库的接口,这是便携式高级终端处理的事实标准。
虽然curses在Unix环境中使用最为广泛,但版本可用于DOS,OS / 2以及其他可能的系统。此扩展模块旨在匹配ncurses的API,这是一个托管在Linux上的开源curses库和Unix的BSD变体。
我在这里找到了终端控制器:Using terminfo for portable color output & cursor control。它看起来比网站名称更便携(MacOS在评论中提到 - 虽然有变化)。
这是一个用法示例,显示进度条:
class ProgressBar:
"""
A 3-line progress bar, which looks like::
Header
20% [===========----------------------------------]
progress message
The progress bar is colored, if the terminal supports color
output; and adjusts to the width of the terminal.
"""
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
def __init__(self, term, header):
self.term = term
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
raise ValueError("Terminal isn't capable enough -- you "
"should use a simpler progress dispaly.")
self.width = self.term.COLS or 75
self.bar = term.render(self.BAR)
self.header = self.term.render(self.HEADER % header.center(self.width))
self.cleared = 1 #: true if we haven't drawn the bar yet.
self.update(0, '')
def update(self, percent, message):
if self.cleared:
sys.stdout.write(self.header)
self.cleared = 0
n = int((self.width-10)*percent)
sys.stdout.write(
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
self.term.CLEAR_EOL + message.center(self.width))
def clear(self):
if not self.cleared:
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL)
self.cleared = 1