linux - script - Bash-Actualizar el título de la terminal ejecutando un segundo comando
script linux ejemplos (8)
En mi terminal en Ubuntu, a menudo ejecuto programas que siguen funcionando durante mucho tiempo. Y como hay muchos de estos programas, sigo olvidándome de qué terminal es para qué programa, a menos que repase todos esos. Así que quería encontrar una manera de actualizar el título de mi terminal al nombre del programa, siempre que ejecutara un comando. No quiero hacerlo manualmente.
Yo uso gnome-terminal, pero la respuesta no debería depender de eso. Básicamente, si soy capaz de ejecutar un segundo comando, entonces simplemente puedo usar el comando gconftool para actualizar el título. Así que esperaba encontrar una manera de capturar el comando en bash y actualizar el título después de cada comando. ¿Cómo puedo hacer eso?
El OP pidió bash
, pero a otros les podría interesar saber que ( como se mencionó anteriormente ) es mucho más fácil usar el shell zsh
. Ejemplo:
# 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" }
En preexec
, $1
contiene el comando como está escrito (requiere que el historial de shell esté habilitado, lo que parece ser una suposición justa), $2
el comando expandido (alias de shell, etc.) y $3
el comando "muy expandido" (cuerpos de función de shell). (more)
Estoy haciendo algo como esto, para mostrar mi pwd
en el título, que podría modificarse para hacer lo que quieras con el título:
function title { echo -en "/033]2;$1/007"; }
function cd { dir=$1; if [ -z "$dir" ]; then dir=~; fi; builtin cd "$dir" && title `pwd`; }
Acabo de lanzar esto en mis ~/.bash_aliases
.
Actualizar
Me encontré con errores extraños con mi respuesta original. Terminé desarmando el Ubuntu PS1 predeterminado y dividiéndolo en partes solo para darme cuenta de que una de las partes era el título:
# simple prompt
COLOR_YELLOW_BOLD="/[/033[1;33m/]"
COLOR_DEFAULT="/[/033[0m/]"
TITLE="/[/e]0;/u@/h:/w/a/]"
PROMPT="/w/n$ "
HUH="${debian_chroot:+($debian_chroot)}"
PS1="${COLOR_YELLOW_BOLD}${TITLE}${HUH}${PROMPT}${COLOR_DEFAULT}"
Sin dividir en variables, se vería así:
PS1="/[/033[1;33m/]/[/e]0;/u@/h:/w/a/]${debian_chroot:+($debian_chroot)}/w/n$ /[/033[0m/]"
He probado tres métodos, todo está bien, use cualquiera para su placer.
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
tenga en cuenta que si usa $ BASH_COMMAND, no reconoce el alias de bash, y use PROMPT_COMMAND para mostrar el comando finalizado, pero use el comando trap show running running.
Prueba esto:
trap ''echo -ne "/033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")/007"'' DEBUG
Gracias a la history 1
funciona incluso con expresiones complicadas como:
true && (false); echo $? | cat
Para qué enfoques se basan en $ BASH_COMMAND o $ @ fail. Por ejemplo las pantallas de simon :
true | echo $? | cat
Gracias a Gilles y Simon por proporcionar inspiración.
Puede configurar bash
para que envíe una determinada secuencia de escape al terminal cada vez que inicie un programa externo. Si usa la secuencia de escape que usan los terminales para actualizar sus títulos, su problema debería resolverse.
Lo he usado antes, así que sé que es posible. pero no puedo recordarlo de la cabeza y no tengo tiempo para investigar los detalles ahora mismo.
Según la necesidad de posicionar automáticamente las ventanas de masilla , he modificado mi archivo /etc/bash.bashrc
en un sistema Debian / Ubuntu. He publicado el contenido completo para completar, pero el bit relevante para comienza en el # Display command ...
línea de comentarios.
# 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
Veo lo que Stoutie está tratando de hacer, excepto que es mucho más trabajo del necesario. Y no causa todo tipo de otras cosas potencialmente malas que pueden ocurrir como resultado de la redefinición de ''cd'' y poner todas esas pruebas solo para cambiar directorios. Bash ha incorporado soporte para la mayor parte de esto.
Puedes poner esto en tu .bashrc en cualquier lugar después de configurar tu indicador de PS1 actual (de esta manera, solo lo preparará)
# If this is an xterm set the titlebar to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="/[/e]0;/u@/h: /w/a/]$PS1"
;;
*)
;;
esac
Tengo algunas respuestas para usted :) Tiene razón en que no debería importar que esté usando gnome-terminal, pero sí importa qué shell de comando está usando. Esto es mucho más fácil en zsh
, pero en lo que sigue voy a suponer que estás usando bash
, y que es una versión bastante reciente (> 3.1).
Ante todo:
¿Qué variable de entorno contendría el ''comando'' actual?
Hay una variable de entorno que tiene más o menos lo que quieres: $BASH_COMMAND
. Solo hay un pequeño enganche, que es que solo te mostrará el último comando en una tubería. Tampoco estoy 100% seguro de lo que hará con las combinaciones de subshells :)
Así que esperaba encontrar una manera de capturar el comando en bash y actualizar el título después de cada comando.
He estado pensando en esto, y ahora que entiendo lo que quieres hacer, me di cuenta de que el problema real es que necesitas actualizar el título antes de cada comando. Esto significa que las variables de entorno $PROMPT_COMMAND
y $PS1
están disponibles como posibles soluciones, ya que solo se ejecutan después de que se devuelve el comando.
En bash
, la única forma en la que puedo pensar para lograr lo que quiere es (ab) usar la SEÑAL DE DEPURACIÓN. Así que aquí hay una solución: pega esto al final de tu .bashrc
:
trap ''printf "/033]0;%s/007" "${BASH_COMMAND//[^[:print:]]/}"'' DEBUG
Para solucionar el problema con las tuberías, he estado jugando con esto:
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
¡Pero no prometo que sea perfecto!