pLu*_*umo 12 top terminal gnome-terminal cursor
跑步时
top -n1 | head
Run Code Online (Sandbox Code Playgroud)
终端的光标消失。跑步top -n1能把它带回来。
在 Ubuntu 16.04 和 CentOS 7.5中gnome-terminal和tilix中测试。
运行top -n1 | tail没有这个问题,所以我认为,top输出结束时的某些内容让光标重新出现,而在打印时不会执行head。
是什么原因造成的,我怎样才能更优雅地找回光标?
Mr *_*unz 17
恕我直言,最好的方法是top使用“批处理”模式(-b标志),该模式旨在用于非交互式用例,例如管道到另一个程序或文件。
所以这
top -n1 -b | head
Run Code Online (Sandbox Code Playgroud)
不会在没有光标的情况下离开外壳。
至于光标消失的原因...
由于top是一个交互式程序,它与终端“混淆”以获取输入、滚动内容等,并隐藏光标。
当终止时,它必须恢复光标和它在被调用之前找到的显示状态,它通过向终端本身发送一个或多个控制代码来实现。
通过通过管道传递命令head,此控制代码将无法通过(head默认情况下仅打印前 10 行,并且两者的输出top以及用于恢复终端状态的控制代码始终大于 10 行)。
事实上,如果你给出head足够多的行来打印,光标就会出现!
例如,
top -n1 | head -n 100
Run Code Online (Sandbox Code Playgroud)
在我的系统上留下一个光标。
我无法在任何地方重新创建这种行为,但它确实出现在 Ubuntu 18.04 上
检查顶部输出的十六进制转储是有益的:
$ top -n1 | head -n1 | xxd
00000000: 1b5b 3f31 681b 3d1b 5b3f 3235 6c1b 5b48 .[?1h.=.[?25l.[H
00000010: 1b5b 324a 1b28 421b 5b6d 746f 7020 2d20 .[2J.(B.[mtop -
00000020: 3133 3a34 333a 3034 2075 7020 3120 6d69 13:43:04 up 1 mi
00000030: 6e2c 2020 3120 7573 6572 2c20 206c 6f61 n, 1 user, loa
00000040: 6420 6176 6572 6167 653a 2030 2e38 312c d average: 0.81,
00000050: 2030 2e35 342c 2030 2e32 321b 2842 1b5b 0.54, 0.22.(B.[
00000060: 6d1b 5b33 393b 3439 6d1b 2842 1b5b 6d1b m.[39;49m.(B.[m.
00000070: 5b33 393b 3439 6d1b 5b4b 0a [39;49m.[K.
$ top -n1 | tail -n1 | xxd
00000000: 1b5b 3f31 326c 1b5b 3f32 3568 1b5b 4b .[?12l.[?25h.[K
$
Run Code Online (Sandbox Code Playgroud)
特别是,开始的序列0x1b5b3f是ANSI 转义序列,它实际上是元数据来控制光标位置和文本颜色等内容。
特别是,在 top 输出的第一行的开头有ESC [?25l,在最后一行的末尾是ESC [?25h。根据维基百科页面,这些是隐藏和显示光标的相应代码。
通过管道top -n1输出到head,终端将在开始时收到 hide-cursor 命令,但在结束时不会收到 show-cursor 命令,因此光标将保持不可见,直到某些其他操作再次将其打开。
@MrShunz 建议使用-b选项top是正确的。此选项禁用 top 输出中的所有 ANSI 转义序列,而仅输出纯 ASCII 可打印文本。在执行topwith期间不会损坏游标-b:
$ top -b -n1 | head -n1 | xxd
00000000: 746f 7020 2d20 3133 3a35 393a 3236 2075 top - 13:59:26 u
00000010: 7020 3138 206d 696e 2c20 2031 2075 7365 p 18 min, 1 use
00000020: 722c 2020 6c6f 6164 2061 7665 7261 6765 r, load average
00000030: 3a20 302e 3134 2c20 302e 3036 2c20 302e : 0.14, 0.06, 0.
00000040: 3037 0a 07.
$
Run Code Online (Sandbox Code Playgroud)