實時輸出不佔用目前提示位置的命令?
我有命令:
ps -o pid,user,%cpu,command | head -n 30
我想列印上述命令的輸出並對其進行更新,但在不刷新整個終端(alacritty)的情況下保持與先前輸出相同的列印輸出。
基本上目的是執行腳本並實時觀察 ps 命令的變化,但不會弄亂目前提示位置,並且不應該刷新終端(可能導致閃爍)。
我嘗試
watch
了命令,但它會吞噬整個終端/tmux 的窗格。我也嘗試過 tput 但無法正常工作。
先謝謝了。
假設終端在游標下方至少有 30 行¹,並且您的終端支持這些轉義序列,您可以使用
sc
(save cursor) 和rc
(restore cursor) 轉義序列: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
要在執行時隱藏游標並在每次提示之前沒有執行此操作的外殼中斷時清除螢幕底部,您可以做到。
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>
¹:游標向上<n>
行(在 中
zsh
,您可以跳過聲明所有這些$sc
/$rc
… 變數並使用$terminfo[sc]
…)在
zsh
中,您還可以使用它的調度程序ps
在 zle 消息區域中顯示該輸出,同時仍然能夠使用 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 行。如果您要報告的流程較少,這可能沒有必要。