1

Whenever I connect to one my remote Ubuntu machines, gnome-terminal reflects the fact that I am on the remote machine in the title, using format much like "$USER"@"$(hostname -s)": "$PWD". I very much like this default behavior, as it lets me know what machine I am running commands on.

When I connect to my FreeBSD machine as a user that uses sh as it's default shell, the title for gnome-terminal does not update.

I have put the following in my .shrc file:

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

So here's the problem. I have found many useful resources, but none seem to indicate how can I set the title using POSIX-complaint sh. Here is the one I found most useful (I was actually able to set the title on bash and ksh using this as reference):

How to change the title of an xterm: examples for different shells

I think I'm nearly there, but I can't seem to figure out what I need to give sh to set the title bar.

1 Answers1

0

In trying to find a way to get a pretty prompt on POSIX sh, I ran into two limitations of the sh implementation of PS1 that I had to hack around:

  1. While the \w in the PS1 var does work, it does not expand $HOME to ~

  2. While you can use PS1 to update the prompt on the terminal, it does not seem possible to update the xterm title using the PS1 variable. The ESC and BEL characters fail to set the title as one would expect if they were using bash or ksh

Here was the final result, it works very nicely. It needs to be added to your .shrc file (make sure that PS1 is not already defined first):

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
}

Note that the prompt will be wrapped in parenthesis. This is just a personal reminder to myself that I am on FreeBSD and not Ubuntu. If you prefer a more traditional looking prompt, just use this:

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
}

You probably want to remove the "/usr$HOME"*) condition if you are on Linux. It serves no purpose unless you are on FreeBSD, where /home is typically a symlink to /usr/home.