【发布时间】:2026-01-29 23:20:05
【问题描述】:
我知道我可以返回该行并用\r 覆盖其内容。
现在我怎样才能进入上一行来改变它?
或者有没有办法打印到控制台窗口中的特定光标位置?
我的目标是使用 PHP 创建一些自刷新的多行控制台应用程序。
【问题讨论】:
标签: php linux formatting console
我知道我可以返回该行并用\r 覆盖其内容。
现在我怎样才能进入上一行来改变它?
或者有没有办法打印到控制台窗口中的特定光标位置?
我的目标是使用 PHP 创建一些自刷新的多行控制台应用程序。
【问题讨论】:
标签: php linux formatting console
使用ANSI escape codes 移动光标。例如:Esc [ 1 F。要将转义字符放入字符串中,您需要以数字形式指定其值,例如 "\x1B[1F"
作为sujoy suggests,您可以使用PHP ncurses 以更抽象的方式移动光标。
虽然大多数“控制台”允许使用 ANSI 转义码,但其他类型的终端使用不同的字符序列,ncurses 提供了一个独立于终端的标准化 API。如果您有兴趣,请快速查看/etc/termcap(然后是man terminfo)。
更新:Lars Wirzenius' answer 有一个有用的背景摘要。几年前我还在terminals上写过一篇短文。
【讨论】:
Linux 虚拟控制台模拟了一个老式的显示终端,虽然并不完美。有关硬件示例,请参阅Wikipedia on 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))然后写入输出是最简单的。
【讨论】:
我的目标是创建一些自刷新的多行控制台应用程序 PHP
对于你想要达到的目标ncurses 是要走的路。
【讨论】:
您应该阅读有关 ncurses 的信息。在shell中,您可以通过以下方式排成一行:
tput cuu1
请参阅man terminfo 了解更多选项。
但是执行shell命令来移动光标是相当绝望的。
【讨论】:
您只需使用键盘上的向上和向下箭头即可滚动浏览控制台历史记录,但也有 history 命令。使用 man history 了解更多信息
【讨论】: