重定向输出时 openSUSE Leap 15.3 上的 ps aux --headers 问题

重定向输出时 openSUSE Leap 15.3 上的 ps aux --headers 问题

以下在 openSUSE Leap 15.3 上运行正常。正如当我使用终端上的滚动条向后滚动屏幕时,每个输出屏幕都会重复标题行:

ps aux --headers

但是,当我将输出重定向到文件或另一个命令时,我只能在输出的第一行获得初始标题行。每个输出屏幕的预期标题行丢失。实际过程的输出显示正常。重现问题的 2 个命令:

ps aux --headers | less

或者

ps aux --headers  >> ps.out

使用 tee 命令进行屏幕和文件输出时出现同样的问题:

ps aux --headers | tee ps-tee.out

我使用以下命令查看是否会出现任何错误,但错误文件为空:

ps aux --headers 1>>ps.out 2>>ps.error

当 grep 查找标题行时,它只匹配一次:

dave@localhost:~> ps aux --headers | egrep RSS | egrep -v grep
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dave@localhost:~> 

我使用的是 bash,但也尝试了 ksh、csh 和 zsh 并遇到了同样的问题。

从 gui 桌面启动终端 (KDE/Konsole) 以及使用 Putty ssh 到盒子时,都会出现此问题。

除了 openSUSE Leap 15.3 之外,SUSE Linux Enterprise 15.3 和旧版本的 SUSE Linux Enterprise 11.4 上也会出现同样的问题(仅尝试通过 Putty 进行 ssh 会话)。

当将输出重定向到命令或文件时,CentOS 6/7 和 Mint 19(使用 bash)按预期工作,如我可以看到每个输出屏幕的标题行。

当 CentOS/Mint 的 grep 可以看到多个标题行时,这就是我对 openSUSE 的期望:

[dave@centos1 ~]$ ps aux --headers | egrep RSS  
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dave      3682  0.0  0.0   4424   816 pts/0    S+   11:58   0:00 egrep RSS
[dave@centos1 ~]$

关于为什么重定向导致附加/后续标题行从重定向输出中消失的任何提示/解释将不胜感激。

答案1

您正在将输出重定向到远离终端的位置。因此,该ps命令不再包含有关显示器尺寸的信息,因此它会假设显示器非常宽且非常长。毕竟,如果您将其重定向到一个文件并在不同大小的终端中查看该文件,则先前终端上的大小假设不再适用。如果在浏览寻呼机和第一个屏幕后调整窗口大小,以前的大小假设不再适用,那么它也可能毫无意义。

答案2

我想说 ps 从 stdout(在 OpenSuse 中)和其他系统上的 stderr 获取屏幕大小。我在这里没有看到问题,只是行为上的偏差。如果您确实需要这些额外的行,请使用 awk 脚本

lines=$(tput lines); ps ax | awk 'BEGIN {lines='$lines'-2} NR==1 {l=$0;print;next} (NR-1)%lines==0 { print l} { print }'

相关内容