Bash (Español)/Prompt customization (Español)

From ArchWiki
Esta traducción de Bash/Prompt customization fue revisada el 2022-10-30. Si existen cambios puede actualizarla o avisar al equipo de traducción.

Bash tiene varios prompts que se pueden personalizar para aumentar la productividad, el atractivo estético y la credibilidad de los nerds.

Prompts

Bash tiene cuatro "cadenas de prompt" que se pueden personalizar:

  • PS0 se muestra después de cada orden, antes de cualquier salida.
  • PS1 es el prompt principal que se muestra antes de cada orden, por lo que es el que la mayoría de la gente personaliza.
  • PS2 es el prompt secundario que se muestra cuando una orden necesita más entrada (por ejemplo, una orden de varias líneas).
  • PS3 no es muy usado. Es el prompt que se muestra para el select incorporado de Bash que muestra menús interactivos. A diferencia de los otros prompts, no expande secuencias de escape Bash. Por lo general, lo personalizaría en el script donde se usa select en lugar de en su .bashrc.
  • PS4 tampoco se usa comúnmente. Se muestra al depurar scripts de bash para indicar los niveles de direccionamiento indirecto. El primer carácter se repite para indicar niveles más profundos.

Todos los prompts se personalizan configurando la variable correspondiente a la cadena deseada (generalmente en ~/.bashrc), por ejemplo:

PS2='> '

Técnicas

Si bien uno puede simplemente configurar su prompt en una cadena simple, existe una variedad de técnicas para hacer que el indicador sea más dinámico y útil.

Secuencias de escape Bash

Al imprimir la cadena de mensaje, Bash busca ciertos caracteres con barra invertida y los expandirá en cadenas especiales. Por ejemplo, \u se expande en el nombre de usuario actual y \A se amplía a la hora actual. Así que un PS1 de '\A \u $ ' se imprimiría como 17:35 usuario $ .

Véase la página del manual bash(1) § PROMPTING o el manual de referencia de Bash para obtener una lista de secuencias de escape.

Secuencias de escape Terminfo

Además de los caracteres de escape reconocidos por Bash, la mayoría de los terminales reconocen secuencias de escape especiales que afectan a la propia terminal en lugar de imprimir caracteres. Por ejemplo, pueden cambiar el color de los caracteres impresos posteriores, mover el cursor a una ubicación arbitraria o borrar la pantalla. Estas secuencias de escape pueden ser algo ilegibles y pueden variar de un terminal a otro, por lo que están documentadas en la base de datos terminfo. Para ver qué capacidades admite su terminal, ejecute:

$ infocmp

Los nombres de las capacidades (la parte antes de =) se pueden buscar en terminfo(5) para obtener una descripción de lo que hacen. Por ejemplo, setaf establece el color de primer plano de cualquier texto que se imprima después. Para obtener el código de escape de una capacidad, puede utilizar la orden tput. Por ejemplo

$ tput setaf 2

Imprime la secuencia de escape para establecer el color de primer plano en verde.

Nota: Si le fallan las órdenes tput, asegúrese de haber establecido el valor TERM correcto para su intérprete de órdenes. Por ejemplo, si configuró xterm en lugar de xterm-256color, tput setaf solo funcionará con los números de color 0-7.

Para incorporar prácticamente estas capacidades en su prompt, puede utilizar la sustitución de órdenes y la interpolación de cadenas de Bash. Por ejemplo

GREEN="\[$(tput setaf 2)\]"
RESET="\[$(tput sgr0)\]"

PS1="${GREEN}mi prompt${RESET}> "
mi prompt>
Nota: La página de manual de Bash recomienda envolver la salida tput en \[ \]. Esto ayuda a Bash a ignorar los caracteres no imprimibles para que calcule correctamente el tamaño del prompt. La envoltura (wrap) no funcionará con la sustitución de órdenes, en cuyo caso se debe utilizar \1 \2 sin procesar.

Secuencias de escape ANSI

Desafortunadamente, es posible que falten secuencias de escape ANSI válidas en la base de datos terminfo de su terminal. Esto es especialmente común con las secuencias de escape para funciones más nuevas, como la compatibilidad con 256 colores. En ese caso, no puede utilizar tput, debe introducir la secuencia de escape manualmente.

Véase Wikipedia:es:Código escape ANSI para ejemplos de secuencias de escape. Cada secuencia de escape comienza con un carácter de escape literal, que puede introducir utilizando la secuencia de escape Bash \e. Entonces por ejemplo, \e[48;5;209m establece el fondo en un color melocotón (si tiene compatibilidad con 256 colores) y \e[2;2H mueve el cursor cerca de la esquina superior izquierda de la pantalla.

En los casos en que las secuencias de escape de Bash no sean compatibles (como PS3), puede obtener un carácter de escape literal utilizando el printf incorporado de Bash:

ESC=$(printf "\e")
PEACH="$ESC[48;5;209m"

Incrustar órdenes

Si desea añadir la salida de algúna orden a su prompt, puede verse tentado a utilizar la sustitución de órdenes. Por ejemplo, para añadir la cantidad de memoria libre a su prompt, podría intentar:

PS1="$(awk '/MemFree/{print $2}' /proc/meminfo) prompt > "
53718 prompt >
53718 prompt >
53718 prompt >

Pero esto no funciona, ya que la cantidad de memoria que se muestra es la misma cada vez. Esto se debe a que la orden se ejecuta una vez, cuando se configura PS1 por primera vez, y nunca más. El truco es simplemente evitar la sustitución, ya sea escapando $ o definiéndolo entre comillas simples; de cualquier manera, se sustituirá cuando se muestre el prompt:

PS1="\$(awk '/MemFree/{print \$2}' /proc/meminfo) prompt > "
# o
PS1='$(awk "/MemFree/{print \$2}" /proc/meminfo) prompt > '

Para evitar que las órdenes largas hagan que tu PS1 sea enorme, puedes definir funciones:

free_mem()
{
    awk '/MemFree/{print $2}' /proc/meminfo
}

PS1='$(free_mem) prompt > '
Nota: Puede utilizar secuencias de escape terminfo/ANSI dentro de funciones sustituidas pero no escapes de Bash. En particular, \[ \] no funcionará para los caracteres no imprimibles circundantes. En su lugar, puede utilizar los escapes octales \001 y \002 (por ejemplo utilizando printf o echo -e).

PROMPT_COMMAND

Si se establece la variable PROMPT_COMMAND, se evaluará justo antes de que se muestre PS1. Esto se puede utilizar para lograr efectos bastante potentes. Por ejemplo, puede reasignar PS1 en función de alguna condición o realizar alguna operación en su historial de Bash cada vez que ejecuta una orden.

Nota: PROMPT_COMMAND por lo general, no debe usarse para imprimir caracteres directamente en el prompt. Bash no cuenta los caracteres impresos fuera de PS1, lo que hará que coloque incorrectamente el cursor y borre los caracteres. Utilice PROMPT_COMMAND para configurar PS1 o véase #Incrustar órdenes.
Sugerencia: Si PROMPT_COMMAND se vuelve demasiado complicado, bash-preexec (una implementación preexec de Zsh y de las funciones de enlace (hook) precmd para Bash) pueden hacerlo más fácil de mantener.

Escapes entre la entrada y la salida de la orden

Puede afectar su texto de entrada en Bash al no restablecer las propiedades del texto al final de su PS1. Por ejemplo, insertar tput blink al final de su PS1 hará que sus órdfenes escritas parpadeen. Sin embargo, este efecto también continuará a través de la salida de la orden ya que las propiedades del texto no se restablecen cuando pulsa Intro.

Para insertar secuencias de escape después de escribir una orden pero antes de que se muestre la salida, puede configurar PS0. Alternativamente, puede atrapar la señal DEBUG de Bash, que se envía justo antes de que se ejecute cada orden:

$ trap 'tput sgr0' DEBUG

Personalizar prompts del superusuario

Para asegurarse de que sabe cuándo está ejecutando como superusuario (root), puede personalizar su prompt de superusuario para que se destaque claramente (¿quizás parpadeando en rojo?). Esto se hace personalizando el prompt de Bash como de costumbre, pero en el directorio de inicio del superusuario, /root. Comience copiando los archivos de esqueleto /etc/skel/.bash_profile y /etc/skel/.bashrc a /root, luego edite /root/.bashrc como desee.

Ejemplos

Colores

Sugerencia: infocmp muestra la cantidad de colores con los que trabaja tput, por ejemplo colors#8.

Para ver la gama completa de colores que soporta su terminal, puede utilizar un ciclo simple con tput (cambie setab a setaf para los primeros planos de texto):

for C in {0..255}; do
    tput setab $C
    echo -n "$C "
done
tput sgr0
echo

Si eso no funciona (y no puede solucionarlo configurando el valor TERM correcto), puede probar las diferentes secuencias de escape manuales:

# colores estándar
for C in {40..47}; do
    echo -en "\e[${C}m$C "
done
# colores de alta intensidad
for C in {100..107}; do
    echo -en "\e[${C}m$C "
done
# 256 colores
for C in {16..255}; do
    echo -en "\e[48;5;${C}m$C "
done
echo -e "\e(B\e[m"

Para cambiar los escapes manuales de fondo a primer plano, el rango de color estándar es 30..37, el rango de alta intensidad es 90..97, y el 48 debe cambiarse a 38 para 256 colores.

Capacidades comunes

Las siguientes capacidades de terminfo son útiles para la personalización de prompt y son compatibles con muchos terminales. #1 y #2 son marcadores de posición para argumentos numéricos.

Capacidad Secuencia de escape Descripción
Atributos de texto
blink \e[5m activar texto parpadeante
bold \e[1m activar texto en negrita
dim \e[2m activar texto atenuado
rev \e[7m activar vídeo inverso (cambiar texto/colores de fondo)
sitm \e[3m activar texto en cursiva
ritm \e[23m desactivar texto en cursiva
smso \e[7m activar texto resaltado
rmso \e[27m desactivar texto resaltado
smul \e[4m activar texto subrayado
rmul \e[24m desactivar texto subrayado
setab #1 \e[4#1m establecer el color de fondo #1 (0-7)
setaf #1 \e[3#1m establecer el color de texto #1 (0-7)
sgr0 \e(B\e[m restablecer atributos de texto
Movimiento del cursor
sc \e7 guardar la posición del cursor
rc \e8 restaurar la posición del cursor guardada
clear \e[H\e[2J borrar la pantalla y mover el cursor a la parte superior izquierda
cuu #1 \e[#1A mover el cursor hacia arriba #1 filas
cud #1 \e[#1B mover el cursor hacia abajo #1 filas
cuf #1 \e[#1C mover el cursor hacia la derecha #1 columnas
cub #1 \e[#1D mover el cursor hacia la izquierda #1 columnas
home \e[H mover el cursor a la parte superior izquierda
hpa #1 \e[#1G mover el cursor a la columna #1
vpa #1 \e[#1d mover el cursor a la fila #1, primera columna
cup #1 #2 \e[#1;#2H mover el cursor a la fila #1, columna #2
Eliminación de caracteres
dch #1 \e#1P eliminar #1 caracteres (como el retroceso)
dl #1 \e#1M eliminar #1 líneas
ech #1 \e#1X borrar #1 caracteres (sin mover el cursor)
ed \eE[J borrar hacia la parte inferior de la pantalla
el \e[K borrar hacia el final de la línea
el1 \e[1K borrar hacia el principio de la línea

Visualizar códigos de salida

Utilizando el mismo truco de incrustar órdenes, puede retrasar la interpolación de variables especiales de Bash como $?. Entonces, el siguiente mensaje muestra el código de salida de la orden anterior:

PS1="\$? > "
# o
PS1='$? > '
0 > true
0 > false
1 >

Esto se puede hacer más interesante utilizando condicionales y funciones:

exitstatus()
{
    if [[ $? == 0 ]]; then
        echo ':)'
    else
        echo 'D:'
    fi
}
PS1='$(exitstatus) > '
:) > true
:) > false
D: >

Posicionar el cursor

Es posible mover el cursor por la pantalla dentro de PS1 para que aparezcan diferentes partes del prompt en diferentes ubicaciones. Sin embargo, para asegurarse de que Bash coloca el cursor y la salida en la posición correcta, debe mover el cursor a la posición original una vez que haya terminado de imprimir en otro lugar. Esto se puede hacer utilizando las capacidades de tput sc y rc para guardar y restaurar la posición del cursor. El patrón general para un prompt que mueve el cursor es:

PS1="\[$(tput sc; cursor-moving code) positioned prompt stuff $(tput rc)\] normal prompt stuff"

Donde todo el bloque del prompt reposicionado está envuelto en \[ \] para evitar que Bash lo cuente como parte del prompt normal.

Texto justificado a la derecha

La forma más sencilla de imprimir texto en el lado derecho de la pantalla es utilizar printf:

rightprompt()
{
    printf "%*s" $COLUMNS "prompt derecho"
}

PS1='\[$(tput sc; rightprompt; tput rc)\]prompt izquierdo > '
prompt izquierdo > prompt derecho

Esto crea un campo de tamaño variable justificado a la derecha %*s y establece su tamaño en el número actual de columnas del terminal $COLUMNS.

Posicionar arbitrariamente

La capacidad cup mueve el cursor a una posición específica en la pantalla, por ejemplo tput cup 20 5 mueve el cursor a la línea 20, columna 5 (donde 0 0 es la esquina superior izquierda ). cuu, cud, cuf y cub (arriba, abajo, adelante, atrás) mueven el cursor en relación con su posición actual. Por ejemplo tput cuf 10 mueve el cursor 10 caracteres a la derecha. Puede utilizar las variables LINES y COLUMNS en los argumentos para mover el cursor en relación con los bordes inferior y derecho. Por ejemplo, para alejarse 10 líneas y 5 columnas de la esquina inferior derecha:

$ tput cup $((LINES - 11)) $((COLUMNS - 6))

Personalizar el título de la ventana del terminal

El título de la ventana del terminal se puede personalizar de la misma manera que el prompt: imprimiendo secuencias de escape en el intérprete de órdenes. Por lo tanto, es común que los usuarios incluyan personalizaciones de título de ventana en su prompt. Aunque esto es técnicamente una característica de xterm, muchos terminales modernos lo admiten. La secuencia de escape a utilizar es 'ESC]2;nuevo títuloBEL donde ESC y BEL son los caracteres de escape y campana. Al utilizar #Secuencias de escape Bash, cambiar el título en su prompt parece tal que así:

PS1='\[\e]2;nuevo título\a\]prompt > '

Por supuesto, su cadena del título de la ventana puede incluir resultados de incrustar órdenes o variables como $PWD, de modo que el título cambie con cada orden.

Véase también