如何设置 zsh shell 标题而不执行两次命令替换?

如何设置 zsh shell 标题而不执行两次命令替换?

我的 zsh 配置包含setopt PROMPT_SUBST.当我在 shell 命令中使用命令替换时,我发现它被执行了两次。这可能会导致我的脚本速度变慢甚至出现错误。

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

我发现这是由于我在 中设置 xterm 窗口标题而发生的preexec()。 (注意:我没有使用 xterm,但相同的代码适用于许多终端,例如 WSL 终端、wslterm 和 tmux。)如何以不执行命令替换的方式设置标题?注:当前标题设置代码为:

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

答案1

不幸的是,所有终端都是不同的,唯一的方法似乎是为每个终端编写不同的preexecand 。precmd为了在 tmux 中获取工作选项卡标题,我必须添加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\\"

相关内容