PROMPT_COMMAND puede contener declaraciones bash ordinarias, mientras que la variable PS1 también puede contener caracteres especiales, como '\ h' para el nombre de host, en la variable.
Por ejemplo, aquí está mi indicador de bash que usa tanto PROMPT_COMMAND como PS1. El código bash en PROMPT_COMMAND determina en qué rama de git podría estar y lo muestra en el indicador, junto con el estado de salida del último proceso ejecutado, el nombre de host y el nombre de base del pwd. La variable RET almacena el valor de retorno del último programa ejecutado. Esto es conveniente para ver si hubo un error y el código de error del último programa que ejecuté en la terminal. Tenga en cuenta el exterior 'que rodea toda la expresión PROMPT_COMMAND. Incluye PS1 para que esta variable se vuelva a evaluar cada vez que se evalúe la variable PROMPT_COMMAND.
PROMPT_COMMAND='RET=$?;\
BRANCH="";\
ERRMSG="";\
if [[ $RET != 0 ]]; then\
ERRMSG=" $RET";\
fi;\
if git branch &>/dev/null; then\
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2);\
fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
La salida de ejemplo se ve así en un directorio que no es de git:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
y en un directorio de git ves el nombre de la rama:
sashan@dhcp-au-122 rework mybranch $
Actualizar
Después de leer los comentarios y la respuesta de Bob, creo que es mejor escribirlo como él lo describe. Es más fácil de mantener que lo que escribí originalmente anteriormente, donde la variable PS1 se establece dentro de PROMPT_COMMAND, que en sí misma es una cadena súper complicada que bash evalúa en tiempo de ejecución. Funciona, pero es más complicado de lo necesario. Para ser justos, escribí PROMPT_COMMAND para mí hace unos 10 años y funcionó y no pensé demasiado en ello.
Para aquellos curiosos sobre cómo modifiqué mis cosas, básicamente puse el código para PROMPT_COMMAND en un archivo separado (como Bob describió) y luego repitió la cadena que pretendo que sea PS1:
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
ERRMSG=" $RET"
fi
if which git &>/dev/null; then
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2)
else
BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
y en mi .bashrc
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
if git branch &>/dev/null ; then\
. Redirige tanto stdout como stderr a / dev / null. tldp.org/LDP/abs/html/io-redirection.htmlPROMPT_COMMAND
.Don't set PS1 in PROMPT_COMMAND! Set variables in PROMPT_COMMAND and use them in PS1
PS1
línea dentro dePROMPT_COMMAND
es desventajoso. Es un código útil perfecto. En contraste con la respuesta de Bob, laPS1
variable se construyó correctamente. Esto permite un indicador de bash mucho más sofisticado dependiendo de su situación real.PS1
interiorPROMPT_COMMAND
no sirve para nada. es un ejemplo de cómo no hacerlo. construyaPS1
una vez.bash_profile
, utilice comillas simples en lugar de comillas dobles, de modo que las sustituciones de variables se evalúen durante cada solicitud.La diferencia es que PS1 es la cadena de solicitud real utilizada y PROMPT_COMMAND es un comando que se ejecuta justo antes de la solicitud. Si desea la forma más sencilla y flexible de crear un mensaje, intente esto:
Pon esto en tu .bashrc:
Luego escriba un script (bash, perl, ruby: su elección) y colóquelo en ~ / bin / bash_prompt.
El guión puede usar cualquier información que desee para construir un mensaje. En mi opinión, esto es mucho más simple porque no tienes que aprender el lenguaje de sustitución algo barroco que se desarrolló solo para la variable PS1.
Podría pensar que podría hacer lo mismo simplemente configurando PROMPT_COMMAND directamente en ~ / bin / bash_prompt y configurando PS1 en la cadena vacía. Al principio, esto parece funcionar, pero pronto descubre que el código de línea de lectura espera que PS1 se establezca en el indicador real, y cuando se desplaza por las contraseñas en el historial, las cosas se complican como resultado. Esta solución temporal hace que PS1 siempre refleje el indicador más reciente (ya que la función establece el PS1 real utilizado por la instancia de invocación del shell), y esto hace que la línea de lectura y el historial de comandos funcionen bien.
fuente
PS1
enPROMPT_COMMAND
! Establezca variablesPROMPT_COMMAND
y utilícelas enPS1
. De lo contrario, perderá la capacidad de usar lasPS1
secuencias de escape como\u
o\h
. Tienes que reinventarlosPROMPT_COMMAND
. Eso podría ser posible, pero no es posible evitar la pérdida de\[
y\]
que marcan el principio y el final de los caracteres no imprimibles. Esto significa que no puede usar colores sin confundir al terminal sobre la longitud del mensaje. Y esto confundereadline
al editar un comando que genera dos líneas. Al final tienes un gran lío en la pantalla.PROMPT_COMMAND
se ejecuta antes de imprimirPS1
. No veo ningún problema de configuraciónPS1
desde el interiorPROMPT_COMMAND
, porque una vezPROMPT_COMMAND
finalizado, se imprimirá el shellPS1
, que se modificó desdePROMPT_COMMAND
(o en este caso, desde dentroprompt_command
)?export PS1='$(~/bin/bash_prompt)'
hace lo mismo que el error se ve cuerdoDe
man bash
:Si simplemente desea establecer la cadena de solicitud, usar
PS1
solo es suficiente:Si desea hacer algo más justo antes de imprimir el mensaje, utilice
PROMPT_COMMAND
. Por ejemplo, si desea sincronizar las escrituras en caché en el disco, puede escribir:fuente
PS1
sin necesidadPROMPT_COMMAND
, ya que la secuencia que establece el título se puede incluir enPS1
envuelto con\[
y\]
.PS1
, simplemente se configurará en la subcapa, por lo que no puede recuperar su valor. pero su ejemplo es trivialPS1='$(sync)user \u on host \h$ '
la diferencia es que
PROMPT_COMMAND
, arruinará su indicador de bashPS1
sustitutos\H
y amigosPROMPT_COMMAND
ejecuta su contenido,PS1
utiliza su contenido como indicador.PS1
realiza la expansión de variables y la sustitución de comandos en cada indicador, no es necesario utilizarloPROMPT_COMMAND
para asignar un valorPS1
o ejecutar código arbitrario. puedes hacerlo fácilmenteexport PS1='$(uuidgen) $RANDOM'
una vez.bash_profile
, solo usa comillas simplesfuente
Sí, para tratar de concretar esto:
PROMPT_COMMAND
Es una función / variable de conveniencia útil de bash , pero no hay, estrictamente hablando, nada que no se pueda hacer usandoPS1
solo, ¿correcto?Quiero decir, si uno quiere establecer otra variable con alcance fuera del indicador: dependiendo del shell, esa variable probablemente deba declararse primero fuera
$PS1
o (en el peor de los casos) uno podría tener que ponerse elegante con algo esperando en un FIFO antes de llamando$PS1
(y armado de nuevo al final de$PS1
); el\u
\h
podría causar algunos problemas, particularmente si está usando una expresión regular elegante; pero de lo contrario: ¿se puede lograr cualquier cosaPROMPT_COMMAND
mediante el uso de la sustitución de comandos dentro$PS1
(y, tal vez en casos de esquina, subcapas explícitas)?¿Correcto?
fuente