ojos rojos





Hola, les presento un pequeño tutorial sobre cómo diseñar una línea de comandos con ojos rojos.



Todos los que trabajaron en la consola de algunos Linux probablemente notaron la conveniente función de mostrar la carpeta actual, el nombre de usuario, el nombre del servidor y algo más, dependiendo de la distracción en la línea de aviso. Siempre me gustó también. Pero a veces resultaba así:







es difícil "crear" en una línea de tres caracteres, por supuesto que el cursor se mueve a la siguiente línea, pero más bien enfurece aún más que ayuda. Y en algún momento, me dije a mí mismo:







decidí recuperar todo el espacio de la línea de comandos y no volver a dárselo a nadie. La pregunta era cómo cambiar el texto del símbolo del sistema. Resultó ser muy simple, simplemente cambie la variable especial del sistema "PS1".







Sí, puede establecer un nuevo texto de invitación directamente en la terminal. Pero, ¿cómo se guardan los cambios? E incluso sin información sobre el catálogo actual, de alguna manera se siente incómodo y se hace constantemente la pregunta: "¿Dónde estoy?" El archivo ~ / .bashrc ayudará , en él puede guardar el cambio de PS1, y para que la información sobre el directorio actual no ocupe el espacio de trabajo, decidí colocarlo no DENTRO sino SOBRE la línea de comandos. Agregue la siguiente línea al archivo ~ / .bashrc :



PS1='$PWD\n# '


Preste atención a las comillas simples, si usamos comillas dobles, entonces, en lugar de un puntero a la variable $ PWD (una variable del sistema que almacena la ruta completa de la carpeta actual, análoga al comando pwd) , su valor (directorio actual) se escribirá en la cadena de solicitud y se cambiará al moverse desde la carpeta la carpeta no lo será. Tiene este aspecto: la







línea de comando es completamente gratuita, pero el nombre de la carpeta se fusiona con el contenido si ejecuta el comando ls . Tendremos que separar las moscas de las chuletas, el nombre de la carpeta del contenido. Decidí agregar "marcos" para $ PWD agregando líneas "-" en la parte superior e inferior. ¿Cómo saber el número de caracteres en una línea? También existe la variable de sistema $ COLUMNS para esto.... Y para formar rápidamente una cadena con el número requerido de caracteres "-", use el comando printf :



printf -v line "%${COLUMNS}s"


Este comando creará una línea $ variable y la llenará con espacios en la cantidad de $ COLUMNS pero no necesitamos espacios sino "-", para esto usamos el siguiente truco:



line=${line// /-} #     -


Agreguemos este código a ~ / .bashrc



printf -v line "%${COLUMNS}s"
line=${line// /-}
PS1='\n$line\n$PWD\n$line\n# '






Genial, pero si cambiamos el tamaño de la ventana del terminal ahora, el tamaño de las "líneas" no cambiará y la belleza desaparecerá:







Para corregir la situación, transferiremos el nuevo código a la función de información y lo agregaremos a PS1:



info () {
    printf -v line "%${COLUMNS}s"
    line=${line// /-}
    printf "\n$line\n$PWD\n$line\n# "
}
PS1='$(info)'


Puede combinar negocios con placer agregando un "inserto" con el nombre de host en el delimitador superior. El inserto con el nombre estará en el medio, para esto necesitamos calcular el centro de la línea (teniendo en cuenta la longitud del nombre de host y caracteres adicionales):



info () {
    name_length="{ $HOSTNAME }"
    name_length=${#name_length}
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_${HOSTNAME}_S_}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    bot_line=${bot_line// /-}
    top_line=${top_line// /-}
    top_line=${top_line//_S_/ }
    printf "\n$top_line\n$PWD\n$bot_line\n# "
}
PS1='$(info)'






He incluido el nombre de host entre llaves con espacios, pero en lugar de espacios alrededor de $ HOSTNAME , se utilizan los caracteres "_S_", que luego se cambian a espacios. Esto es necesario porque todos los espacios en la línea final se reemplazan con "-" y los espacios deben permanecer dentro del inserto. Agreguemos colores, para esto prepararemos variables con códigos para cambiar el color del texto en el terminal, utilicé los siguientes colores:



RED='\e[31m' # 
GRN='\e[32m' # 
YLW='\e[33m' # 
BLU='\e[34m' # 
MGN='\e[35m' # 
DEF='\e[0m'  #    
BLD='\e[1m'  # 
DIM='\e[2m'  # 


Agreguemos estas variables a nuestro código:



info () {
    name_length="{ $HOSTNAME }"
    name_length=${#name_length}
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME${DEF}_S_$GRN}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    bot_line=$GRN${bot_line// /-}$DEF
    top_line=${top_line// /-}
    top_line=$GRN${top_line//_S_/ }$DEF
    printf "\n$top_line\n$BLD$BLU$PWD$DEF\n$bot_line\n# "
}
PS1='$(info)'






Adelante, el lado derecho parece vacío, puede poner la fecha y la hora allí:



printf -v date "%(%a %d %b %T)T"


Para colocar esto a la derecha, debe agregar una cantidad de espacios después de $ PWD , qué, vamos a contar:



center_space=$[COLUMNS-${#date}-${#PWD}]
((center_space<0)) && center_space=1
...
printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s$DIM$date\n$bot_line\n# "






¿Puedes hacerlo mejor? Por supuesto, agreguemos la salida del estado de git si estamos en la carpeta con el proyecto git :



    git_tst= git_clr=
    [[ -d .git ]] && {
        git_tst=($(git status -c color.ui=never -sb))
        git_tst="GIT ${git_tst[*]} " #   
        git_clr=(GIT $(git -c color.ui=always status -sb))
        git_clr="GIT ${git_clr[*]} " #   
    }
    ...
    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}]
    ...
    printf "\n$top_line\n$BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date\n$bot_line\n\$ "






Tenga en cuenta que git_clr y git_tst se escriben primero como una matriz y luego se convierten en variables. Esto es necesario para eliminar los saltos de línea de la salida de estado de git . ¿Pero dónde están los ojos? Ahora habrá O_o ojos, creemos una matriz con un par básico de ojos:



eyes=(O o ∘ ◦ ⍤ ⍥)


Y contemos su número:



en=${#eyes[@]}


Agreguemos un símbolo de boca:



mouth='_'


Y hagamos un generador de caras aleatorias:



face () {
    printf "$YLW${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}$DEF"
}


Los ojos estarán ubicados en los bordes del campo de información, es necesario tenerlos en cuenta al calcular el número de espacios en el medio, prepararemos una variable aparte para esto:



face_tst='O_o  o_O'
...
center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]
printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "






¿Cómo sonrojar tus ojos? Sentado frente a la computadora durante mucho tiempo, sin dormir. En stackoverflow.com me encontré con una pregunta interesante , el autor pregunta: "¿cómo cambiar el color en la línea de comandos a rojo si falla el último comando?" Esto me llevó a la idea de ojos rojos. Agreguemos a la función de información recordando el estado de finalización del último comando:



info () {
    error=$?
    ...
}


Y cambiemos la función de la cara para que verifique la variable $ error y, según su valor, pinte los ojos en rojo o amarillo:



face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}






Bueno , mis ojos se pusieron rojos, pero puedes agregar algo más. Agreguemos una verificación para la variable $ debian_chroot :



[[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=
...
name_length="{ $HOSTNAME$chrt }"
...
printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"


Y cambiemos el texto en el título de la ventana del terminal:



PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac


El encabezado mostrará la cara y el directorio actual, pero tendrás que modificar ligeramente la función de la cara para que dibuje la cara sin códigos de color, se mostrarán en el encabezado como solo texto, pasaremos algún parámetro (por ejemplo, "1") a la función de cara , agrega una marca dentro de la función, si se da el primer argumento, la salida del cañón sin colorear:



face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \
             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}






Guión final:



RED='\e[31m' # 
GRN='\e[32m' # 
YLW='\e[33m' # 
BLU='\e[34m' # 
MGN='\e[35m' # 
DEF='\e[0m'  #    
BLD='\e[1m'  # 
DIM='\e[2m'  # 
eyes=(O o ∘ ◦ ⍤ ⍥) en=${#eyes[@]} mouth='_'
face () {
    [[ $error -gt 0 ]] && ecolor=$RED || ecolor=$YLW
    [[ $1 ]] && printf "${eyes[$[RANDOM%en]]}$mouth${eyes[$[RANDOM%en]]}" \
             || printf "$ecolor${eyes[$[RANDOM%en]]}$YLW$mouth$ecolor${eyes[$[RANDOM%en]]}$DEF"
}
info () { error=$? git_tst= git_clr=
    [[ -d .git ]] && {
        git_tst=($(git -c color.ui=never status -sb))
        git_tst="GIT ${git_tst[*]} " #   
        git_clr=($(git -c color.ui=always status -sb))
        git_clr="GIT ${git_clr[*]} " #   
    }
    [[ $debian_chroot ]] && chrt="($debian_chroot)" || chrt=
    name_length="{ $HOSTNAME$chrt }"
    name_length=${#name_length}
    face_tst='O_o  o_O'
    top_line_left=$[(COLUMNS-name_length)/2]
    top_line_right=$[COLUMNS-(top_line_left+name_length)]
    printf -v top_line "%${top_line_left}s{_S_$DEF$BLD$HOSTNAME$chrt${DEF}_S_$GRN}%${top_line_right}s"
    printf -v bot_line "%${COLUMNS}s"
    printf -v date  "%(%a %d %b %T)T"
    top_line=${top_line// /-}
    top_line=$GRN${top_line//_S_/ }$DEF
    bot_line=$GRN${bot_line// /-}$DEF
    center_space=$[COLUMNS-${#date}-${#PWD}-${#git_tst}-${#face_tst}]
    ((center_space<0)) && center_space=1
    printf "\n$top_line\n$(face) $BLD$BLU$PWD$DEF%${center_space}s$git_clr$DIM$date $(face)\n$bot_line\n\$ "
}
PS1='$(info)'; case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;$(face 1) \w\a\]$PS1";; esac


Eso es todo, ¡gracias por tu atención!) Suscríbete, eso es todo, el proyecto está en la barra de información github ¡ Crea, inventa, prueba!)



control de cuidado
"#" "$"?)



(*) (*)



All Articles