连接到使用 sh 作为默认 shell 的远程计算机后,如何使标题栏动态更新自身?

连接到使用 sh 作为默认 shell 的远程计算机后,如何使标题栏动态更新自身?

每当我连接到远程 Ubuntu 机器时,gnome-terminal 都会反映我在标题中的远程机器上的事实,使用的格式与"$USER"@"$(hostname -s)": "$PWD".我非常喜欢这种默认行为,因为它让我知道我正在哪台机器上运行命令。

当我以使用 sh 作为默认 shell 的用户身份连接到 FreeBSD 计算机时,gnome-terminal 的标题不会更新。

我已将以下内容放入我的 .shrc 文件中:

PS1='['"$USER"'@\h \w'
case "$USER" in
    root)
        PS1="${PS1}]# "
        ;;
    *)
        PS1="${PS1}]$ "
        ;;
esac

esc="$(printf '\033')"
bel="$(printf '\007')"

case "$TERM" in
    xterm)
        #cannot get this part to work
        PS1='['"${esc}"'0;'"${USER}"'@\h \w'"$bel"']'"$PS1"
        ;;
    *)
        ;;
esac

所以问题就在这里。我发现了许多有用的资源,但似乎没有一个资源表明如何使用 POSIX-complaint sh 设置标题。这是我发现最有用的一个(我实际上能够使用它作为参考在 bash 和 ksh 上设置标题):

如何更改 xterm 的标题:不同 shell 的示例

我想我已经快到了,但我似乎不知道需要给 sh 提供什么来设置标题栏。

答案1

在尝试找到一种在 POSIX sh 上获得漂亮提示的方法时,我遇到了 PS1 的 sh 实现的两个限制,我必须解决这些限制:

  1. 虽然var\w中的PS1确实有效,但它不会扩展$HOME~

  2. 虽然您可以使用PS1来更新终端上的提示,但似乎无法使用该PS1变量来更新 xterm 标题。如果使用 bash 或 ksh,则ESCBEL字符无法按照预期设置标题

这是最终的结果,效果非常好。需要将其添加到您的 .shrc 文件中(首先确保 PS1 尚未定义):

update_prompt() {
    case "$PWD" in
        "$HOME"*)
            pretty_pwd="~${PWD#*"${HOME}"}"
            ;;
        "/usr$HOME"*)
            pretty_pwd="~${PWD#*"/usr${HOME}"}"
            ;;
        *)
            pretty_pwd="$PWD"
            ;;
    esac

    case "$TERM" in
        xterm*|rxvt*)
            PS1="($USER@\\h $pretty_pwd)\\$ "
            ;;
        *)
            ;;
    esac

    printf "\\033]0;(%s@$(hostname -s): %s)\\007" "$USER" "$pretty_pwd"
}

update_prompt

cd() {
    command cd "$@" && update_prompt
}

请注意,提示将包含在括号中。这只是个人提醒我自己,我使用的是 FreeBSD,而不是 Ubuntu。如果您喜欢更传统的提示,只需使用:

update_prompt() {
    case "$PWD" in
        "$HOME"*)
            pretty_pwd="~${PWD#*"${HOME}"}"
            ;;
        "/usr$HOME"*)
            pretty_pwd="~${PWD#*"/usr${HOME}"}"
            ;;
        *)
            pretty_pwd="$PWD"
            ;;
    esac

    case "$TERM" in
        xterm*|rxvt*)
            PS1="$USER@\\h $pretty_pwd\\$ "
            ;;
        *)
            ;;
    esac

    printf "\\033]0;%s@$(hostname -s): %s\\007" "$USER" "$pretty_pwd"
}

update_prompt

cd() {
    command cd "$@" && update_prompt
}

"/usr$HOME"*)如果您使用的是 Linux,您可能希望删除该条件。除非您使用 FreeBSD,否则它没有任何用处,其中/home通常是/usr/home.

相关内容