zsh에는 명령이 실행되기 전에 실행되는 사전 실행 후크가 있다는 것을 알고 있지만, 명령이 시작된 후 출력이 화면에 표시되기 전에 실행되는 후크가 있습니까? 실제 출력이 있는지 여부에 따라 무언가를 표시하고 싶기 때문에 이 질문을 드리는 것입니다.
예:
cd dir
아무것도 출력하지 않고
ls dir
무언가를 출력합니다 .
Output:\n
이 예에서는 ls 디렉토리가 표시되기 전에 표시 하고 싶지만 cd
표시되지 않기 때문에 실행될 때는 표시하지 않습니다. 나는 그것이 다음과 같이 보이기를 원합니다 :
~ $: cd dir
~/dir $: ls .
Output:
total 464
drwxr-xr-x+ 55 eddie staff 1.8K May 2 11:07 .
drwxr-xr-x 6 root admin 204B Apr 22 13:48 ..
~/dir $
나는 단지 CD와 LS를 포장하고 싶지 않습니다. 이것들은 모두 예시입니다. 나는 그것이기를 바란다모든주문하다.
답변1
있을 수 없습니다시사후크는 명령이 터미널이나 다른 파일에 무언가를 출력할 때 쉘이 전혀 관련되지 않기 때문입니다.
후크는 명령줄에서 시작된 프로세스나 스레드가 tty 장치에 열린 파일 설명자에 대한 첫 번째 쓰기 시스템 호출을 수행할 때 실행되는 명령에 있어야 합니다. 또는 일부 IPC 메커니즘을 사용하여 명령의 stdout 및 stderr(명령 동작에 대한 영향을 최소화하기 위한 의사-tty 쌍)를 리디렉션하고 Output:
무언가가 수신될 때 이를 삽입해야 합니다. 그럼에도 불구하고 이는 매우 복잡하고 침해적일 수 있습니다.
제가 할 일은 아니지만 다음과 같이 시도해 볼 수 있습니다.
preexec() {
printf '%-*s' $COLUMNS "Output:"
read -sdR $'pos_before?\e[6n'
}
precmd() {
read -sdR $'pos_after?\e[6n'
[[ $pos_after != $pos_before ]] || printf '\r'
}
set +o promptsp
즉, 명령 출력을 실행하기 전에 Output:
커서를 화면의 오른쪽 가장자리로 이동하고(따라서 다음 내용은 다음 줄의 시작 부분에 기록됩니다) 현재 커서 위치를 에 기록합니다 $pos_before
.
다음 프롬프트 이전에 커서 위치를 다시 쿼리하고, 이동하지 않은 경우 다음 프롬프트가 해당 위치를 덮어쓰도록 커서를 줄의 시작 부분으로 다시 이동합니다 Output:
. promptsp
이를 방해하기 때문에 비활성화합니다 .
¹이 pty 기반 접근 방식은 다음 expect
을 통해 구현할 수 있습니다.
#! /usr/bin/expect -f
set x 0
set timeout -1
stty raw -echo
log_user 0
spawn -noecho zsh
# tell zsh to send a special sequence before the prompt (precmd)
# and a different one before each command (preexec)
send {precmd() printf "\1\1"; preexec() printf "\2\2";set +o promptsp}
send "\r"
# wait for the second prompt
expect "\1\1"
# set our x flag when the preexec string has been output and reset
# it upon precmd. write "Output:" if some character is received while
# the flag is up.
expect {
-re "^\2\2" {
set x 1; exp_continue
}
-re "^\1\1" {
set x 0; exp_continue
}
-re "^.\[^\1\2\]*" {
if {$x} {send_user "Output:\n"; set x 0}
send_user -- "$expect_out(buffer)"
exp_continue
}
-i $user_spawn_id -re .+ {
send -- $expect_out(buffer); exp_continue
}
}