在 Linux 控制台中返回一行?
我知道我可以返回该行并用 \r
覆盖其内容。
现在我怎样才能进入上一行来改变它?
或者有没有办法打印到控制台窗口中的特定光标位置?
我的目标是使用 PHP 创建一些自刷新的多行控制台应用程序。
I know I can go back the line and overwrite its contents with \r
.
Now how can I go up into the previous line to change that?
Or is there even a way to print to a specific cursor location in the console window?
My goal is to create some self-refreshing multiline console app with PHP.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用ANSI转义码移动光标。例如:
Esc [ 1 F
。要将转义字符放入字符串中,您需要以数字方式指定其值,例如 "\x1B[1F"As sujoy 建议,你可以使用 PHP ncurses 以更抽象的方式移动光标。
虽然大多数“控制台”允许 ANSI 转义码,但其他类型的终端使用不同的字符序列,而
ncurses
提供了独立于终端的标准化 API。如果您有兴趣,请快速查看/etc/termcap
(然后查看man terminfo
)。更新:Lars Wirzenius 的回答对背景有一个有用的总结。几年前,我还写了一篇关于终端的短文。
Use ANSI escape codes to move the cursor. For example:
Esc [ 1 F
. To put the Escape character in a string you'll need to specify its value numerically, for example "\x1B[1F"As sujoy suggests, you can use PHP ncurses for a more abstract way to move the cursor.
Whilst most "consoles" allow ANSI escape codes, other sorts of terminal use different character sequences,
ncurses
provides a standardised API that is terminal independent. Have a quick look at/etc/termcap
(and thenman terminfo
) if you are interested.Update: Lars Wirzenius' answer has a useful summary of the background. Some years ago I also wrote a short article on terminals.
Linux 虚拟控制台模拟旧式显示终端,尽管并不完美。有关硬件示例,请参阅有关 VT-100 的维基百科。
这些终端从串行端口读取数据,并将其显示在屏幕上。他们还在串行端口的输入流中查找特殊字节,并以其他方式对其进行操作。例如,换行符('\n',字节值 10)将转到下一行的开头,回车符('\r',字节值 13)将转到当前行的开头。
更有趣的是,一个 ASCII ESC 字节 (27) 将启动一个命令序列,该序列几乎可以对光标或显示器执行任何操作。一个这样的序列可能会将光标移动到屏幕的左上角,另一个序列可能会将光标移动到给定的行和列。第三个可能会清除屏幕,第四个可能会使文本以反色显示。
每个终端制造商都会发明自己的命令序列(他们也不总是从 ESC 开始),然后根据他们可以让新版本的硬件做什么来更改它们。如果制造商添加了颜色或简单的图形,就会产生新的序列。
使每个应用程序适应每个终端以及对命令序列的每次更改将是一项艰巨的任务。与将每个 Web 应用程序适应新的浏览器版本进行比较。
像往常一样,解决方案是添加一个抽象层。在 Unix 中,最初的抽象称为
termcap
,由文件/etc/termcap
和读取该文件的库组成。该文件将指定为每个终端模型的每个逻辑操作发送的实际命令序列。因此,vt102
终端模型会将“清除屏幕”操作映射到\033[2J
。这使得应用程序程序员可以根据逻辑运算进行思考,这要简单得多。当然,还不够简单... termcap 库并没有想象中那么好,因此开发了另外两个库:
curses
提供了更高的抽象级别,包括用户输入,以及 terminfo程序员可以更轻松地定义终端及其使用。在现代,
ncurses
是curses
的免费重新实现,而terminfo
几乎完全取代了termcap
。此外,ANSI 还定义了一些基于数字终端的“标准”序列,几乎每个终端仿真器都使用这些序列,至少大部分都使用这些序列,Linux 虚拟控制台就是其中之一。很少有人拥有实际的物理终端了。对于您想要执行的操作,
ncurses
或tput
命令可能最有用。或者您可能认为只清除整个屏幕(请参阅clear
(1))并写入输出是最简单的。The Linux virtual consoles emulate an old-time display terminal, although not perfectly. See Wikipedia on VT-100 for an example of the hardware.
These terminals read data from a serial port, and displayed it on the screen. They also looked for special bytes in the input stream from the serial port and acted upon them in other ways. For example, the newline character ('\n', byte value 10) would go to the beginning of the next line, and the carriage return character ('\r', byte value 13) would go the beginning of the current line.
More interestingly, an ASCII ESC byte (27) would start a command sequence which could to almost anything to the cursor or display. One such sequence might move the cursor to the top left of the screen, another to a given row and column. A third one might clear the screen, and a fourth one might make text be displayed in reverse colors.
Every manufacturer of terminals would invent their own command sequences (and they didn't always start with ESC either), and then change them depending on what they could make new versions of their hardware do. If a manufacturer added colors or simple graphics, those resulted in new sequences.
Adapating every application to every terminal and every change to the command sequences would have been a big task. Compare it with adapting every web application to a new browser version.
As usual, the solution is to add a layer of abstraction. In Unix, the initial abstraction was called
termcap
, and consisted of the file/etc/termcap
, and a library to read the file. The file would specify the actual command sequences to send for each logical operation for each terminal model. So avt102
terminal model would map the operation "clear the screen" to the\033[2J
. This allowed application programmers to think in terms of the logical operations, which was much simpler.Of course, not simple enough... The termcap library was not as good as it might have been, so two other libraries were developd:
curses
provided a higher abstraction level, including user input, and terminfo made the terminal definitions and their use by programmers easier.In modern times,
ncurses
is a free re-implementation ofcurses
andterminfo
has pretty much replacedtermcap
completely. Also, ANSI has defined some "standard" sequences, based on the Digital terminals, and almost every terminal emulator uses those, at least mostly, and the Linux virtual console is one of them. Very few people have actual physical terminals anymore.For what you're trying to do,
ncurses
or thetput
command may be most useful. Or you may decide that just clearing the whole screen (seeclear
(1)) and writing output then is easiest.对于您想要实现的目标
ncurses
是要走的路。For what you are trying to achieve
ncurses
is the way to go.你应该阅读有关 ncurses 的内容。在 shell 中,您可以通过以下方式进行排队:
请参阅
man terminfo
了解更多选项。但是执行 shell 命令来移动光标是非常绝望的。
You shoud read about ncurses. In shell, you can go one line up by:
See
man terminfo
for more options.But executing shell command to move cursor around is quite desperate.
您只需使用键盘上的向上和向下箭头即可滚动浏览控制台历史记录,但还有历史命令。使用人类历史了解更多信息
You just you the up and down arrows on the keyboard to scroll through console history but there is also the history command. Find out more using man history