명령 대체를 두 번 수행하지 않고 zsh 쉘 헤더를 설정하는 방법은 무엇입니까?

명령 대체를 두 번 수행하지 않고 zsh 쉘 헤더를 설정하는 방법은 무엇입니까?

내 zsh 구성에는 setopt PROMPT_SUBST.셸 명령에서 명령 대체를 사용할 때 두 번 실행되는 것으로 나타났습니다. 이로 인해 스크립트가 느려지거나 버그가 발생할 수 있습니다.

% setopt PROMPT_SUBST
% echo $(echo executed >&2)
executed
executed

.NET에서 xterm 창 제목을 설정했기 때문에 이런 일이 발생했다는 것을 알았습니다 preexec(). (참고: 저는 xterm을 사용하지 않지만 WSL 터미널, wslterm 및 tmux와 같은 많은 터미널에서 동일한 코드가 작동합니다.) 명령 대체를 수행하지 않는 방식으로 헤더를 설정하려면 어떻게 해야 합니까? 참고: 현재 제목 설정 코드는 다음과 같습니다.

preexec () {
    print -Pn "\ek$2\e\\"
}
precmd () { 
    print -Pn "\ekzsh\e\\"
}

답변1

불행히도 모든 터미널은 다르며 유일한 방법은 각 터미널마다 다른 터미널을 작성하는 것 같습니다 preexec. precmdtmux에서 작업 탭 제목을 얻으려면 set -g allow-rename on.tmux.conf에 추가하거나 tmux set -g allow-rename on명령을 실행하지 않고 제목을 설정하는 함수는 다음과 같습니다.

preexec () { 
    local cmd=$2
    printf "\033k%s\033\\" $cmd
}
precmd () {
    printf "\033kzsh\033\\"
}

보다 포괄적인 솔루션을 위해서는 각 문제에 대해 서로 다른 기술이 필요합니다 $TERM. tmux는 를 사용하여 감지되지 않습니다 $TERM.

if [[ -n $TMUX ]]; then
    preexec () { 
        local cmd=$2
        printf "\033k%s\033\\" $cmd
    }
    precmd () { 
        printf "\033kzsh\033\\"
    }
else
    # Set xterm/terminal/whatever titles when commands are running:
    case $TERM in
        linux)
            ;;
        *xterm*|rxvt|rxvt-unicode|rxvt-256color|(dt|k|E)term)
            preexec() {
                # TODO
            }
            precmd() {
                # TODO
            }
            ;;
        *screen*)
            preexec() {
                # TODO
            }
            precmd() {
                # TODO
            }
            ;;
    esac
fi

preexec모든 터미널에서 테스트할 가치가 있는 일부 명령은 다음과 같습니다.

print -Pn "\e]0;${cmd}\a"
print -Pn "\ek${cmd}\e\\"

관련 정보