Modificando el prompt - Documentacion

Anuncio
Modificando el prompt de bash
Por Xento Figal (c) 2004 bajo licencia FDL
•
Objeto del documento
•
¿Que es el prompt?
•
¿Donde se encuentran los archivos del prompt?
•
¿Por que modificar el prompt?
•
Modificando el prompt
•
Variables de entorno
•
Secuencias de escape
Comunes
Colores
Movimientos del cursor Trabajando con funciones
•
Funciones como variables.
Funciones como programas.
Ejemplos utiles (o inutiles) •
Prompt extenso con funciones especiales.
Prompt con mucha informacion y lento. •
Documentacion a tener en cuenta
•
Sobre el documento
Objeto del documento
El presente documento pretende servir de ayuda a quienes nunca han modificado o usado estas caracteristicas de bash. Con ejemplos utiles y explicaciones sencillas, no se pretende por tanto abarcar los aspectos mas complejos relacionados con
bash, aqui tan solo se dara una idea global de como modificar el aspecto del interprete de bash, para documentacion mas
extendida sobre bash consulte la seccion documentacion.
Si usted usa un shell distinto a bash, tal vez este documento no le sea de mucha utilidad.
indice
¿Que es el prompt?
El prompt es el interprete de bash, el interprete posee una apariencia modificable , generalmente es esta:
[usuario/dominio directorio]$ Esto realmente no es mas que una salida de comandos a una variable de nuestro shell, la variable es $PS1, existen mas
variables pero nos vamos a centrar en la que nos interesa (PS1) que es donde se define el aspecto de nuestro prompt. indice
¿Donde se encuentra el prompt?
El prompt de linux se puede definir en la variable de entorno $PS1 que a su vez se puede definir en el archivo .bashrc en el
$HOME, o bien de manera general para toda la maquina en /etc/bashrc, si optamos por modificar el prompt de el usuario o
usuarios, deberemos modificar la variable $PS1 de $HOME~.bashrc de lo contrario modificaremos el de toda la maquina, sea
quien sea el usuario (/etc/bashrc).
Aunque esto tratandose de Linux tambien se puede modificar como veremos mas adelante, pero de momento dejemos este
concepto como esta.
indice
¿Por que modificar el prompt?
Principalmente nos basamos en la utilidad, en la comodidad y en el control visual de la propia maquina. En el prompt podemos visualizar lo que se nos ocurra, al contrario de otros sistemas, con bash podemos almacenar una
cantidad importante de datos en memoria, esto en MsDos era casi inpensable, logicamente hay que tener en cuenta que; a
cuanta mas memoria = uso mas lento de la interfaz de comandos, esto se hace particularmente importante cuando
introducimos muchos comandos, variables, o su salida si se prefiere asi, en el prompt, a este concepto se hace referencia en
otra parte del documento.
En los sistemas multiusuario la modificacion del prompt puede ser muy util, puesto que nos permite mostrar el texto que
nosotros deseemos, esto nos abre un abanico muy extenso de opciones, P.ejm: mostrar las cuotas de los usuarios, los
servicios a los que tienen acceso, etc...
indice
Modificando el prompt
Nos vamos a basar en un archivo bashrc muy sencillo, e iremos comentando las lineas y/o instrucciones de este, por supuesto
el ejemplo es extensible hasta donde queramos llegar.
# /etc/bashrc
if [ "`id ­gn`" = "`id ­un`" ­a `id ­u` ­gt 99 ]; then
umask 002
else
umask 022
fi
<­­Lo primero que hacemos es definir umask, umask nos permite tener una configuracion por defecto en materia de
ficheros, directorios y permisos.
Buscamos el id del usuario, filtrando las cuentas que no son menores de 100, esto es por que esas cuentas que estan por
debajo de 100 corresponden a "usuarios propios del sistema" (mail, news, apache, etc....) ­­>
[ "$PS1" = "\\s­\\v\\\$ " ] && PS1="\[\[email protected]\u \w]"
<­­ en esta linea definimos la variable PS1, esta es la linea del prompt en si, en este caso veriamos el nombre del host, el
simbolo @ el usuario y el directorio actual de trabajo ­­>
Probablemente el aspecto de un archivo bashrc sera mas amplio, incorporando mas funciones.
Pero sin lugar a dudas lo que es evidente, es que es un script para el bash y como tal se puede modificar "al gusto", vamos a
ver como podemos hacer un prompt mas personal.
indice
Variables de entorno
Nos tenemos que referir a ellas casi por obligacion, una variable de entorno es como cualquier otra, un nombre asociado a
una cadena de caracteres, esta cadena de caracteres contienen ciertos parametros del propio sistema, como por ejemplo el
editor de texto por defecto, los colores definidos al ejecutar un comando:P.ejm ls (tipo de archivo = color, etc...). Nosotros nos vamos a centrar en las que nos interesan; $SHELL , esta es la variable donde se almacenan los datos del shell (este documento se centra en bash, tenga en
cuenta que para otra shell no podra aplicar esto) en nuestro caso deberiamos tener definida bash $PS1 , En esta se almacena la informacion que mostrar el prompt, el ambito de este documento se centra en esta
variable. •
•
Para trabajar con las variables de entorno se usan los comandos set y env. Si quiere ver las variables asignadas use env, para modificarlas use set, tambien puede ver el valor de una variable
escribiendo echo Nombre_de_la_variable. P.ejem: $set ­u SHELL=BASH Borrariamos la variable SHELL (vea man set o set ­­help para poder conocer todas opciones). indice
Secuencias de escape
La secuencias de escape nos seran de muchisima utilidad, puesto que muestran informacion en el prompt si tener que escribir
codigo nuevo. Secuencias comunes \a
\d
\e
\h
\H
\n
\r
\s
\t
\T
\u
\v
\V
\w
\W
\@
\#
caracter de campana ASCII(07)
Fecha en formato alfanumerico, dia mes hora caracter de escape ASCII(033)
Nombre del dominio sin dominio
Nombre completo del host
caracter de nueva línea
Retorno de carro
Caracter que sigue a la última barra
Hora actual en formato 24­horas HH:MM:S
Hora actual en formato 12­horas HH:MM:SS
Nombre del usuario del shell
La versión del Bash
La versión del paquete del Bash
El directorio actual de trabajo
El nombre completo del directorio actual de trabajo, si esta en /usr/local
La hora actual en formato 12­horas am/pm
El numero de comando del comando actual
El numero del comando actual en el historico, esto puede ser util para ciertos
\!
scripts
\$ Si el UID efectivo es 0, una #, sino, un $, es decir si es root o pertence: 0, si no: $
\[
Inicio de una secuencia de caracteres no imprimibles
\]
Fin de una secuencia de caracteres no imprimibles
\nnn Un caracter correspondiente al numero octal nn
\\
Una contra barra
En bash tambien podemos colorear los resultados, esto tambien se hace desde $PS1, asi como para poder ver los archivos en
colores segun la extension, esta definido en una variable de entorno (P.ejm: LSCOLORS) para el prompt se define en la
variable, pero no como una variable mas de entorno, si no dentro de la misma ($PS1). Para incluir colores debemos encerrarlos entre \[\033[colorm\] donde color es cualquiera de los codigos que se encuentran en
la tabla de abajo, la "m" es necesaria. Para terminar con el codigo de color, \[\033[0m\], en caso contrario todo el texto que aparecera en el buffer sera del color que
previamente hemos definido. indice
Tablas de colores Negro
Azul
Verde
Cyan
Rojo
Purpura
Marron
Gris claro
Gris oscuro
Azul claro
Verde claro
Cyan claro
Rojo claro
Purpura claro
Amarillo
blanco
0;30
0;34
0;32
0;36 0;31
0;35
0;33
0;37
1;30
1;34
1;32
1;36
1;31
1;35
1;33
1;37
Por lo tanto, si quisieramos mostrar la fecha en verde seria: PS1="\[\033[0;32m\][\$(date +%H%M)]$\[\033[0m\]" indice
Movimiento del cursor
Por otro lado, en algunas ocasiones nos puede ser muy util cambiar otros aspectos, como el cursor, esto tiene mas
usabilidad en scripts que en el propio prompt. \033[;H
\033[A
\033[B
\033[C
\033[D
\033[s
\033[u
Coloca el cursor en la linea L, columna C.
Mueve el cursor arriba N lineas
Mueve el cursor abajo N lineas
Mueve el cursor hacia delante N columnas
Mueve el cursor hacia atras N columnas
Guarda la posicion del cursor
Restaura la posicion del cursor
indice
Trabajando con funciones
Una funcion es un trozo de codigo dentro de un programa que se ejecuta como si fuese codigo independiente, puede ver mas
sobre funciones aqui. En nuestro caso usaremos funciones para definir aspectos de la variable $PS1, es decir usaremos funciones para declarar
variables que posteriormente seran mostradas en PS1, la funcion mas basica es esta: function funcion_ejemplo { echo "mi primera funcion" } Si usaramos esta funcion en la variable $PS1 ($PS1="$funcion_ejemplo") nos devolveria un prompt como este: mi primera funcion$ Teniendo esto en cuenta, podemos crear funciones que nos devolveran aspectos interesantes, por ejemplo podemos hacer una
funcion que nos muestre el consumo de memoria, el estado de samba, nuestra i.p publica, el espacio del disco, los archivos
con una UID 0 dentro del mismo directorio de trabajo u otro, etc, etc, hay que tener en cuenta que para trabajar con funciones
es necesario un conocimiento previo de como hacer scripts para bash, tambien hay que tener en cuenta que si mostramos algo
demasiado largo, o que necesite mucho tiempo, repercutira en la rapidez y el aspecto del prompt.
En este ejemplo se ha usado la funcion para definir una variable, de igual manera se pueden declarar variables como si de
cualquier script se tratase.
Funciones como programas. Otra manera de aprovechar el bash, es crear pequeñas aplicaciones, son pequeños scripts dentro de bashrc, se trata de
pequeños trozos de codigo que trabajan de manera "autonoma" son otro tipo de trabajo con funciones, pero que en este caso
al tratarse directamente sobre bashrc las podremos usar cuando estemos en nuestra shell, interesante ¿no?.
Sabiendo que podemos definir el bashrc de cada usuario, esto se presenta de una utilidad importante, pudiendo crear
pequeños programas sin necesidad de que los usen otros usuarios, o facilitar tareas comunes.
P.ejm:
calcula() {
echo "$*" | bc ­l
}
Este ejemplo, si lo incluyeramos dentro de nuestro bashrc nos permitira usar calcula para ejecutar operaciones sobre bc.
[[email protected] \home]$ calcula 2.3 ^3
12.167
[[email protected] \home]$
indice
Ejemplos utiles o inutiles.
A continuacion nos dejamos de tanta teoria y hacemos un poco de practica, un par de prompts potentes, eso si hay una
diferencia entre los dos, el primero resulta mas rapido, pero muestra menos informacion en la linea del prompt, el segundo en
cambio muestra mas informacion en la linea del prompt, pero a cambio es mas lento.
Prompt extenso # /etc/bashrc
if [ "`id ­gn`" = "`id ­un`" ­a `id ­u` ­gt 99 ]; then
umask 002
else
umask 022
fi
if [ "`id ­u`" ­gt 99 ]; then
. /etc/bashrc­luser
fi
if [ "$PS1" ]; then
case $TERM in
xterm*)
PROMPT_COMMAND='echo ­ne "\033]0;${HOSTNAME}: ${PWD}\007"'
;;
*)
;;
esac
infored ()
{
out=$(ifconfig eth0 | grep ­i RX | awk '/bytes/ {print $3$4 }')
in=$(ifconfig eth0 | grep ­i RX | awk '/bytes/ {print $7$8 }')
ip=$(ifconfig eth0 | awk '/addr/ {print $2 }'| cut ­d: ­f2 )
netuna=$(netstat ­tuna | grep ­v Active )
conactv=$(lsof | grep SYN_SENT)
conescucha=$(lsof ­i | grep LISTEN)
echo ­e "\033[0;35m[1]\033[0m" "Ver informacion en pantalla"
echo ­e "\033[0;35m[2]\033[0m" "Ver informacion por puerto"
echo ­e "\033[0;35m[3]\033[0m" "Ver informacion por proceso"
read opcion
case $opcion in
1)
echo ­e "Salida:\033[0;34m$out\033[0m " " Entrada:\033[0;31m$in\033[0m " " IP:$ip "
echo "Conexiones de internet (servicios y establecidas)"
echo "$netuna"
echo "Procesos con conexion"
echo "$conactv"
echo "Procesos esperando conexion"
echo "$conescucha"
;;
2)
read puerto
var1=$(lsof ­i :$puerto)
echo "$var1"
;;
3)
read proceso
var2=$(lsof | grep $proceso)
echo "$var2"
;;
esac
}
function memf {
exec free ­m | grep Mem | awk '{print $4}'
}
function memt {
exec free ­m | grep Mem | awk '{print $3}'
}
function cuotas {
quotastats | grep drops | awk '{print $5}'
}
[ "$PS1" = "\\s­\\v\\\$ " ] && PS1="\[[$(cuotas)] [\033[1;31m\]$(memt)\[\033[0m\]­\[\033[1;34m\] $(memf)\[\033[0m\]
\W]"
if [ "x$SHLVL" != "x1" ]; then # We're not a login shell
for i in /etc/profile.d/*.sh; do
if [ ­r "$i" ]; then
. $i
fi
done
fi
fi
Como podreis ver dentro de bashrc he creado un par de scripts para poder usarlos desde mi shell, principalmente defino por
un sitio que si no se es root o se tiene 0 como uid se ejecuta el archivo /etc/bashrc­lusers, de lo contrario se continua, ademas
en la funcion infored, introducimos un pequeño programa para mostrar informacion util, despues tambien usamos algunas
funciones para declarar variables y mostrarlas en el mismo prompt.
Prompt que muestra mucha informacion y es muy lento.
# /etc/bashrc
if [ "`id ­gn`" = "`id ­un`" ­a `id ­u` ­gt 99 ]; then
umask 002
else
umask 022
fi
if [ "$PS1" ]; then
if [ ­x /usr/bin/tput ]; then
if [ "x`tput kbs`" != "x" ]; then # We can't do this with "dumb" terminal
stty erase `tput kbs`
elif [ ­x /usr/bin/wc ]; then
if [ "`tput kbs|wc ­c `" ­gt 0 ]; then # We can't do this with "dumb" terminal
stty erase `tput kbs`
fi
fi
fi
case $TERM in
xterm*)
if [ ­e /etc/sysconfig/bash­prompt­xterm ]; then
PROMPT_COMMAND=/etc/sysconfig/bash­prompt­xterm
else
PROMPT_COMMAND='echo ­ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}\007"'
fi
;;
screen)
PROMPT_COMMAND='echo ­ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}\033\\"'
;;
*)
[ ­e /etc/sysconfig/bash­prompt­default ] && PROMPT_COMMAND=/etc/sysconfig/bash­prompt­default
;;
esac
function uptaim {
perl ­le 'my $uptimeinfo = `uptime`;if ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up\s+(\d+)\s+day.?\W\s+(\d+):
(\d+)\W\s+(\d+)\s+\ w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) {print("$2d $3h $4m");}elsif ($uptimeinfo =~ /^\s+
(\d+:\d+\w+|\d+:\d+:\d+)\s+up+\s+(\d+):(\d+)\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W\s+( \d+).(\d+)/igx) {print("$2h
$3m");}elsif ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up\s+(\d+)\s+day.?\W\s+(\d+)\s+min\W\s+(\d+)\s+\
w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) {print("$2d $3m");}elsif ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)
\s+up+\s+(\d+)\s+min\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W \s+(\d+).(\d+)/igx) {print("$2m");}print undef;'
}
function discolibre {
perl ­le 'my($disktotal,$diskusedi);for(`df`){chomp;next if !/^\/dev\/\S+/;next if /(cd|cdrom|fd|floppy)/;/^(\S+)\s+(\S+)\s+
(\S+)/;$disktotal += $2;$diskused += $3;}$disktotal = sprintf("%.2f",$disktotal / 1024 / 1024);$diskused = sprintf("%.
2f",$diskused / 1024 / 1024);print("$diskused­$disktotal");'
}
function memf {
exec free ­m | grep Mem | awk '{print $4}'
}
function memt {
exec free ­m | grep Mem | awk '{print $3}'
}
function cpu {
exec top ­n1 | grep "CPU" | awk '{print $3+$5"%"}'
}
function proc {
exec top ­n1 | grep processes | awk '{print $1}'
}
function date2 {
exec date | awk '{print $1"­"$3"­"$2" "$6 }'
}
function users {
exec top ­n1 | grep users | awk '{print $5" Users"}'
}
[ "$PS1" = "\\s­\\v\\\$ " ] && PS1="\[[HD: $(discolibre) GB][Ram: \[\033[1;31m\]$(memt)\[\033[0m\]­\[\033[1;34m\]
$(memf)\[\033[0m\] MB][$(cpu) Cpu][$(proc) Proc][$(users)] [$(date2)][$(date +%H:%M)]\[\033[0m\][Total: $(uptaim)]
[\w]
[\u\[\033[1;32m\]@\[\033[0m\]\h\[\033[0m\]:]\ \[\033[1;32m\]$\[\033[0m\]"
if [ "x$SHLVL" != "x1" ]; then # We're not a login shell
for i in /etc/profile.d/*.sh; do
if [ ­r "$i" ]; then
. $i
fi
done
fi
fi
Este prompt mostraria mucha informacion, pero es realmente pesado y lento, aqui no hemos trabajado mucho en funciones
que nos permitan ejecutar codigo a voluntad, si no que directamente les hemos asignado variables y las mostramos en el
prompt.
Se espera que se ilustre bien como modificar un prompt y hacerlo practico a nuestras necesidades, estos ejemplos no son
quizas la mejor manera de hacer las cosas, pero resultan utiles para explicar en que consiste una modificacion del prompt.
indice
Documentacion a tener en cuenta
­[http://xinfo.sourceforge.net/documentos/bash­scripting/]
Una introduccion a la programacion en bash.
­[http://www.tldp.org/LDP/abs/html/]
El imprescindible how­to sobre bash scripting.
indice
Sobre el documento
El presente documento se encuentra bajo terminos de la licencia FDL, se distribuye sin ninguna garantia, esta autorizada la
libre distribucion, modificacion y copia, rogando que se notifique al autor cambios y aportaciones, e incluyendo al autor
original cuando se haga copia total o parcial o cita del mismo, para ver mas detalles consulte la licencia GNU/FDL. 2004 (c) Xento Figal Version 1.0
EOF
indice
Descargar