Bash – Aggiornamento terminale titolo per l’esecuzione di un secondo comando

Sul mio terminale in Ubuntu, mi capita spesso di eseguire programmi che continuare a correre per un lungo periodo di tempo. E dato che ci sono un sacco di questi programmi, io continuo a dimenticare che il terminale è per il programma, a meno che non ho scheda attraverso tutte quelle. Così ho voluto trovare un modo per aggiornare il mio terminale titolo il nome del programma, ogni volta che ho eseguito un comando. Non voglio farlo manualmente.

Io uso gnome-terminal, ma la risposta non dovrebbe in realtà dipendono da questo. In sostanza, Se io sono in grado di eseguire un secondo comando, quindi posso semplicemente utilizzare gconftool comando per aggiornare il titolo. Così mi è stato sperando di trovare un modo per catturare il comando in bash e aggiornare il titolo dopo ogni comando. Come faccio a fare che?

InformationsquelleAutor Neo | 2011-02-22

 

8 Replies
  1. 22

    Ho alcune risposte per te 🙂 Hai ragione che non importa che si sta utilizzando gnome-terminal, ma non importa che cosa il comando shell che si sta utilizzando. Questo è molto più facile in zsh, ma in quello che segue, ho intenzione di assumere che si sta utilizzando bash, e che è una versione abbastanza recente (> 3.1).

    Prima di tutto:

    Che la variabile di ambiente sarebbe
    contenere la corrente di ‘comando’?

    C’è una variabile di ambiente che è più o meno quello che vuoi – $BASH_COMMAND. C’è solo un piccolo intoppo, che è quella di mostrare l’ultimo comando in un tubo. Io non sono sicuro al 100% di quello che farà con combinazioni di subshells, sia 🙂

    Così speravo di trovare un modo per
    catturare il comando in bash e aggiornamento
    il titolo dopo ogni comando.

    Ho pensato a questo, e ora che ho capito cosa vuoi fare, ho capito che il vero problema è che è necessario aggiornare il titolo prima ogni comando. Questo significa che il $PROMPT_COMMAND e $PS1 le variabili di ambiente sono come possibili soluzioni, dato che sono solo eseguito dopo il comando restituisce.

    In bash, l’unico modo che posso pensare di ottenere ciò che si vuole è quello di (ab)usare il DEBUG del SEGNALE. Quindi, ecco una soluzione — stick alla fine del .bashrc:

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

    Di aggirare il problema con i tubi, sono stato a smanettare con questo:

    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

    ma non prometto è perfetto!

    • Grazie una tonnellata. Qui c’è un link da Dennis, l’altra domanda che riguarda l’esatto problema come il mio. davidpashley.com/articles/xterm-titles-with-bash.html. Perché fa parte della documentazione devono essere scavato così in profondità 😉 ?
    • È l’ultima parte della tua risposta corretta? Ricevo: -bash: PROMPT_COMMAND: line 0: syntax error near unexpected token ';' -bash: PROMPT_COMMAND: line 0: ';export PREV_COMMAND=""' quando l’immissione che in fondo il mio ~/.bashrc
    • Io credo di sì, che è esattamente quello che sto usando e funziona. John‘s risposta qui sotto offre un’alternativa (probabilmente meglio) approccio al problema che l’ultima parte della mia risposta sta cercando di risolvere, però, quindi se questo è importante per voi, mi basta andare con la sua soluzione 🙂
    • per me, questo è superiore all’PROMPT_COMMAND soluzioni perché la trappola si verifica prima che il comando viene eseguito e quindi aggiorna il titolo immediatamente. Così, per esempio, se io ssh in un’altra shell, il titolo si riflettono immediatamente invece di aspettare per aggiornare il prompt dopo che mi è uscita dal guscio. così ho finito con function settitle { LASTCMD=$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g"); echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD} ${LASTCMD}\007"; } trap 'settitle' DEBUG nota: a causa di commenti, che non mi piaceva multi-righe che ho aggiunto il punto e virgola, ma in realtà non sto usando un 1-formato di riga
    • per me, che riporta: bash: PROMPT_COMMAND: riga 0: errore di sintassi vicino al token imprevisto ;' -bash: PROMPT_COMMAND: line 0: ;export PREV_COMMAND=””‘
    • hai fatto quello che hai fatto di sbagliato?
    • infine, usa la funzione ” esporta PROMPT_COMMAND=’echo -ne “\033]2;$(storia 1 | sed “s/^[ ]*[0-9]*[ ]*//g”)\007″‘ trappola ‘echo -ne “\033]2;$(storia 1 | sed “s/^[ ]*[0-9]*[ ]*//g”)\007″‘ DEBUG `
    • Quindi, questo funziona per me, ma solo in una certa misura: il titolo di aggiornamenti mentre il comando è in esecuzione, verrà ripristinato il titolo standard una volta che il comando è stato completato. C’è un modo per farlo restare fino al successivo comando? PS – non Possono essere correlati, ma ho dovuto mettere questo in .bash_profile perché non riesco Git Bash a correre .bashrc…

  2. 13

    Provare questo:

    trap 'echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG

    Grazie per la history 1 funziona anche con espressioni complicate come:

    true && (false); echo $? | cat

    Per la quale si avvicina di affidarsi $BASH_COMMAND o [email protected] esito negativo. Per esempio simon‘s visualizza:

    true | echo $? | cat

    Grazie a Gilles e simon per la fornitura di ispirazione.

    • bene, la storia 1 è meglio di $BASH_COMMAND che non rispettano alias di comando, mostra ls -hF –show-controllo-caratteri –color=auto
    • bello 🙂 Ma perché \033]2; invece di \033]0;? OK, l’ho ritrovato tramite askubuntu.com/a/832382/929 leader invisible-island.net/xterm/ctlseqs/… 2 significa solo cambiare il finestra del titolo, mentre 0 include anche il icona nome. A quanto pare si può anche cambiare alcuni colori ci…
    • E ‘ possibile mettere questo nel bashrc senza trappola del primo, e rendendo il titolo, uscita appena il terminale lancia?
  3. 6

    Vedo cosa stoutie sta cercando di fare, tranne che è un lavoro molto più di quanto necessario. E non causare tutti i tipi di altri potenzialmente le cose brutte che possono verificarsi come risultato di ridefinizione di ‘cd’ e mettere in tutti i test solo per cambiare directory. Bash ha un supporto incorporato per la maggior parte di questo.

    Si può mettere nel vostro .bashrc ovunque dopo aver impostato la corrente variabile PS1 (in questo modo non solo si antepone)

    # If this is an xterm set the titlebar to [email protected]:dir
    case "$TERM" in
    xterm*|rxvt*)
        PS1="\[\e]0;\[email protected]\h: \w\a\]$PS1"
        ;;
    *)
        ;;
    esac
    • Alla fine mi sono imbattuto in strani bug con la mia risposta. Così ho finito per raccolta a parte il default PS1 in Ubuntu, e ho scoperto che una delle parti è il titolo. Vedi la mia risposta sopra.
    • Ben suonato! L’aggiornamento è molto più simile a come la mia personale realtà è scritto (variabili per colori e parti) io non uso il default di ubuntu, perché io personalizzare un sacco (git branch sto su, sporco di stato, un sacco di altre cose stupide, il numero di processi in background…) ho solo voluto mostrare come qualcuno potrebbe prendere qualsiasi PS1 e aggiungere un titolo per la semplicità
  4. 2

    L’OP ha chiesto bash, ma altri potrebbero essere interessati a imparare che (come detto sopra) questo è davvero molto più facile utilizzando il zsh shell. Esempio:

    # Set window title to command just before running it.
    preexec() { printf "\x1b]0;%s\x07" "$1"; }
    
    # Set window title to current working directory after returning from a command.
    precmd() { printf "\x1b]0;%s\x07" "$PWD" }

    In preexec, $1 contiene il comando digitato (richiede shell storia per essere abilitato, che sembra essere un presupposto giusto), $2 espanso di comando (shell alias, ecc.) e $3 il “molto esteso” di comando (shell corpo della funzione). (di più)

  5. 1

    Sto facendo qualcosa di simile a questo, per dimostrare la mia pwd nel titolo, che potrebbe essere modificato per fare ciò che si vuole fare con il titolo:

    function title { echo -en "\033]2;$1\007"; }
    function cd { dir=$1; if [ -z "$dir" ]; then dir=~; fi; builtin cd "$dir" && title `pwd`; }

    Ho messo nel mio ~/.bash_aliases.

    Aggiornamento

    Mi sono imbattuto in un bug strano con la mia risposta. Ho finito la raccolta oltre il default di Ubuntu PS1 e scomposizione in parti solo per rendersi conto di una delle parti era il titolo:

    # simple prompt
    COLOR_YELLOW_BOLD="\[\033[1;33m\]"
    COLOR_DEFAULT="\[\033[0m\]"
    TITLE="\[\e]0;\[email protected]\h:\w\a\]"
    PROMPT="\w\n$ "
    HUH="${debian_chroot:+($debian_chroot)}"
    PS1="${COLOR_YELLOW_BOLD}${TITLE}${HUH}${PROMPT}${COLOR_DEFAULT}"

    Senza rompere in variabili, sarebbe simile a questa:

    PS1="\[\033[1;33m\]\[\e]0;\[email protected]\h:\w\a\]${debian_chroot:+($debian_chroot)}\w\n$ \[\033[0m\]"
  6. 0

    È possibile impostare bash in modo tale che invia una determinata sequenza di escape per il terminale ogni volta che si avvia un programma esterno. Se si utilizza la sequenza di escape che i terminali utilizzare per aggiornare i loro titoli, il problema dovrebbe essere risolto.

    Ho usato prima, quindi so che non è possibile. ma non lo ricordo largo della parte superiore della mia testa e non ho il tempo per la ricerca dei dettagli, tuttavia.

    • Che la variabile di ambiente dovrebbe contenere la corrente di “comando”?
  7. 0

    Basato sulla necessità di posizione auto stucco windows ho modificato il mio /etc/bash.bashrc file su un sistema Debian/Ubuntu. Ho postato l’intero contenuto per completezza, ma il relativo bit di inizio il # Display command ... riga di commento.

    # 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)}\[email protected]\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 [email protected]: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
  8. 0

    Ho testato tre metodo, tutto è OK, è possibile utilizzare uno per il vostro piacere.

    export PROMPT_COMMAND='echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"'
    
    trap 'echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG
    
    trap 'echo -ne "\e]0;"; echo -n $BASH_COMMAND; echo -ne "\a"' DEBUG

    si prega di notare se usare $BASH_COMMAND, non riconoscere bash alias, e utilizzare PROMPT_COMMAND a spettacolo finito di comando, ma usare la trappola mostra l’esecuzione di un comando.

Lascia un commento