Bash - Update terminal title by running a second command

后端 未结 8 1472
Happy的楠姐
Happy的楠姐 2020-12-24 13:27

On my terminal in Ubuntu, I often run programs which keep running for a long time. And since there are a lot of these programs, I keep forgetting which terminal is for which

相关标签:
8条回答
  • 2020-12-24 13:47

    Based on the the need to auto position putty windows I have modified my /etc/bash.bashrc file on a Debian/Ubuntu system. I have posted the full contents for completeness but the relevant bit to starts on the # Display command ... comment line.

    # System-wide .bashrc file for interactive bash(1) shells.
    
    # To enable the settings / commands in this file for login shells as well,
    # this file has to be sourced in /etc/profile.
    
    # If not running interactively, don't do anything
    [ -z "$PS1" ] && return
    
    # check the window size after each command and, if necessary,
    # update the values of LINES and COLUMNS.
    shopt -s checkwinsize
    
    # set variable identifying the chroot you work in (used in the prompt below)
    if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
        debian_chroot=$(cat /etc/debian_chroot)
    fi
    
    # set a fancy prompt (non-color, overwrite the one in /etc/profile)
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    
    # Display command run in title which allows us to distinguish Kitty/Putty
    # windows and re-position easily using AutoSizer window utility. Based on a
    # post here: http://mg.pov.lt/blog/bash-prompt.html
    case "$TERM" in
    xterm*|rxvt*)
        # Show the currently running command in the terminal title:
        # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
        show_command_in_title_bar()
        {
            case "$BASH_COMMAND" in
                *\033]0*)
                    # The command is trying to set the title bar as well;
                    # this is most likely the execution of $PROMPT_COMMAND.
                    # In any case nested escapes confuse the terminal, so don't
                    # output them.
                    ;;
                *)
                    echo -ne "\033]0;${USER}@${HOSTNAME}: ${BASH_COMMAND}\007"
                    ;;
            esac
        }
        trap show_command_in_title_bar DEBUG
        ;;
    *)
        ;;
    esac
    
    # Commented out, don't overwrite xterm -T "title" -n "icontitle" by default.
    # If this is an xterm set the title to user@host:dir
    #case "$TERM" in
    #xterm*|rxvt*)
    #    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
    #    ;;
    #*)
    #    ;;
    #esac
    
    # enable bash completion in interactive shells
    if ! shopt -oq posix; then
      if [ -f /usr/share/bash-completion/bash_completion ]; then
        . /usr/share/bash-completion/bash_completion
      elif [ -f /etc/bash_completion ]; then
        . /etc/bash_completion
      fi
    fi
    
    # if the command-not-found package is installed, use it
    if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
            function command_not_found_handle {
                    # check because c-n-f could've been removed in the meantime
                    if [ -x /usr/lib/command-not-found ]; then
                       /usr/bin/python /usr/lib/command-not-found -- "$1"
                       return $?
                    elif [ -x /usr/share/command-not-found/command-not-found ]; then
                       /usr/bin/python /usr/share/command-not-found/command-not-found -- "$1"
                       return $?
                    else
                       printf "%s: command not found\n" "$1" >&2
                       return 127
                    fi
            }
    fi
    
    0 讨论(0)
  • 2020-12-24 13:54

    I have some answers for you :) You're right that it shouldn't matter that you're using gnome-terminal, but it does matter what command shell you're using. This is a lot easier in zsh, but in what follows I'm going to assume you're using bash, and that it's a fairly recent version (> 3.1).

    First of all:

    Which environment variable would contain the current 'command'?

    There is an environment variable which has more-or-less what you want - $BASH_COMMAND. There's only one small hitch, which is that it will only show you the last command in a pipe. I'm not 100% sure what it will do with combinations of subshells, either :)

    So I was hoping to find a way to capture the command in bash and update the title after every command.

    I've been thinking about this, and now that I understand what you want to do, I realized the real problem is that you need to update the title before every command. This means that the $PROMPT_COMMAND and $PS1 environment variables are out as possible solutions, since they're only executed after the command returns.

    In bash, the only way I can think of to achieve what you want is to (ab)use the DEBUG SIGNAL. So here's a solution -- stick this at the end of your .bashrc:

    trap 'printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}"' DEBUG
    

    To get around the problem with pipes, I've been messing around with this:

    function settitle () {
        export PREV_COMMAND=${PREV_COMMAND}${@}
        printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}"
        export PREV_COMMAND=${PREV_COMMAND}' | '
    }
    
    export PROMPT_COMMAND=${PROMPT_COMMAND}';export PREV_COMMAND=""'
    
    trap 'settitle "$BASH_COMMAND"' DEBUG
    

    but I don't promise it's perfect!

    0 讨论(0)
提交回复
热议问题