我有命令:ps -o pid,user,%cpu,command | head -n 30
我想打印上述命令的输出并更新它,但保持打印与之前的输出相同,而不刷新整个终端(alacrtty)。
基本上,目的是运行脚本并实时观察 ps 命令的变化,但不会弄乱当前提示位置,并且不应刷新 how 终端(这可能导致闪烁)。
我尝试了watch
命令,但它会吞掉整个终端/tmux 的窗格。
我也尝试过 tput 但无法让它工作。
先谢谢了。
答案1
假设终端光标下方至少有 30 行,并且您的终端支持这些转义序列,您可以使用sc
(保存光标) 和rc
(恢复光标) 转义序列:
tput sc
while true; do
tput ed
ps -o pid,user,%cpu,command | head -n 30
tput rc
sleep 1
done
(如果您不支持/ / ...,另请参阅echoti sc
或)。$terminfo[sc]
zsh
tput
sc
rc
ed
要在运行时隐藏光标,并在每次提示之前未执行此操作的 shell 中断时清除屏幕底部,您可以这样做。
my_processes() (
trap 'tput rc; tput ed; tput cnorm; exit' EXIT INT
tput sc; tput civis
while true; do
tput ed
ps -o pid,user,%cpu,command | head -n 30
tput rc
sleep 1
done
)
ed
您可以通过减少序列和输出之间的延迟来减少闪烁ps
:
my_processes() (
for c in sc rc ed cnorm civis; do eval "$c=\$(tput $c)"; done
trap 'printf %s "$rc$ed$cnorm"; exit' EXIT INT
printf %s "$sc$civis"
while true; do
printf %s "$ed$(ps -o pid,user,%cpu,command | head -n 30)$rc"
sleep 1
done
)
这些terminfo
功能在手册页中进行了描述terminfo(5)
:
sc
:保存当前光标位置rc
: 将光标恢复到最后一个save_cursor
:的位置ed
:清除到屏幕末尾civis
: 使光标不可见cnorm
:使光标正常显示(撤消civis
/cvvis
)。cuu <n>
1:光标向上<n>
行
(在 中zsh
,您可以跳过声明所有这些$sc
/ $rc
... 变量并使用$terminfo[sc]
...)
在 中zsh
,您还可以使用其调度程序在 zle 消息区域中显示ps
输出,同时仍然能够使用 shell(尽管这会使完成操作更难使用):
zmodload zsh/sched
my-processes() {
if [[ $1 = stop ]]; then
sched -$zsh_scheduled_events[(i)*:$0]
else
if {zle} zle -M "$(ps -o pid,user,%cpu,command | head -n 30)"
sched +1 $0
fi
}
运行my-processes
开始和my-processes stop
停止。您可以通过按键来打开和关闭它:
toggle-my-processes() {
local event
if (( event = zsh_scheduled_events[(I)*:my-processes] )); then
sched -$event
zle redisplay
else
my-processes
fi
}
zle -N toggle-my-processes
bindkey '\ep' toggle-my-processes
(这里绑定的是ESC
p
字符序列,一般是按Alt+时终端发送的P)
yes '' | head -n30; tput cuu 30
如果您愿意,您可以运行以确保光标下方有 30 行。但如果您要报告的进程较少,则可能没有必要。