현재 프롬프트 위치를 차지하지 않는 명령의 실시간 출력?

현재 프롬프트 위치를 차지하지 않는 명령의 실시간 출력?

나는 명령을 가지고 있습니다 :ps -o pid,user,%cpu,command | head -n 30

위 명령의 출력을 인쇄하고 업데이트하고 싶지만 전체 터미널(alacrtty)을 새로 고치지 않고 이전과 동일한 출력을 계속 인쇄하고 싶습니다.

기본적으로 목적은 스크립트를 실행하고 ps 명령 변경을 실시간으로 관찰하는 것입니다. 그러나 현재 프롬프트 위치를 엉망으로 만들지 않고 터미널을 새로 고치지 않고(깜빡거림을 유발할 수 있음).

명령을 시도했지만 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 scor도 참조하세요).$terminfo[sc]zshtputscrced

실행하는 동안 커서를 숨기고 프롬프트가 표시되기 전에 이 작업을 수행하지 않은 쉘 인터럽트가 발생할 때마다 화면 하단을 지우려면 이 작업을 수행할 수 있습니다.

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]...를 사용할 수 있습니다.)

zle에서는 zsh스케줄러를 사용하여 ps쉘을 계속 사용할 수 있으면서 zle 메시지 영역에 출력을 표시할 수도 있습니다(이렇게 하면 완성을 사용하기가 더 어려워지지만).

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문자 시퀀스 입니다 .)AltP


yes '' | head -n30; tput cuu 30원하는 경우 실행하여 커서 아래에 30줄이 있는지 확인할 수 있습니다. 그러나 보고할 프로세스 수가 적은 경우에는 이것이 필요하지 않을 수도 있습니다.

관련 정보