Personalización del bash - Personalización del bash
28 de Octubre de 2005
Linux, Sistemas operativos
Esto se consigue principalmente a través de ficheros de configuración. También son conocidos como "ficheros de inicio" , "ficheros rc" (por "run control", control de arranque), o incluso "ficheros punto (dot files)", porque los nombres de los ficheros siempre empiezan con ".". Recordemos que los ficheros que empiezan por "." no se visualizan normalmente con ls.
Los ficheros de configuración más importantes son los usados por el shell. El shell por defecto de Linux es el bash, y éste es el shell que cubre este capítulo. Antes de empezar a explicar cómo personalizar el bash, tenemos que saber cuales son los archivos que mira.
Arranque del shell
Hay diferentes modos de funcionamiento del bash. Puede funcionar como shell de ingreso, que es el modo en que arranca cuando se ingresa por primera vez. El shell de ingreso debería ser el primer shell que vea.
Otro modo en que puede funcionar bash es como shell interactivo. Este es un shell que presenta un prompt a un humano y espera una entrada de datos. Un shell de ingreso también es un shell interactivo. Una manera de conseguir un shell interactivo sin ingresar en el sistema es, por ejemplo, un shell dentro de xterm. Cualquier shell que sea creado por otro medio distinto del ingreso registrado en el sistema es un shell de no-ingreso.
Finalmente, hay shells no interactivos. Estos shells se usan para ejecutar un archivo de comandos, muy parecidos a los ficheros de procesamiento por lotes del MS-DOS, los archivos que acaban en .BAT. Estas macros de shell funcionan como mini-programas. Aunque son usualmente mucho más lentos que un programa normal compilado, suele ser cierto también que son mucho más fáciles de escribir. Dependiendo del tipo de shell, se usarán distintos tipos de archivo al arrancarlo:
|| Tipo de Shell || Acción ||
|| Ingreso interactivo || Se lee y ejecuta el archivo .bash_profile ||
|| Interactivo || Se lee y ejecuta el archivo .bashrc ||
|| No_interactivo || Se lee y ejecuta la macro de shell ||
Ficheros de arranque
Como muchos usuarios quieren tener mayormente el mismo entorno, sin importar que tipo de shell interactivo acaben teniendo, y sea o no un shell de ingreso, empezaremos nuestra configuración poniendo un comando muy simple en nuestro archivo .bash_profile: "source ~/.bashrc". El comando source ordena al shell que interprete el argumento como una macro de shell. Lo que significa para nosotros es que cada vez que .bash_profile se ejecuta, también se ejecuta .bashrc. Ahora, sólo añadiremos comandos a nuestro archivo .bashrc. Si alguna vez queremos que se ejecute un comando únicamente cuando hemos hecho un ingreso registrado, lo añadiremos a nuestro .bash_profile.
Creando alias
¿Cuales son algunas de las cosas que interesaría personalizar? Esto es algo que creo que el 90% de los usuarios de Bash han puesto en su .bashrc:
alias ll="ls -l"
Este comando define un alias de shell llamado ll que "expande" el comando normal de shell "ls -l" cuando se invoca por el usuario. De modo que, asumiendo que Bash ha leído este comando del fichero .bashrc, podemos teclear ll para conseguir el efecto de "ls-l"_ con solo la mitad de pulsaciones. Lo que ocurre es que cuando tecleamos "ll" y pulsamos |_Intro_|, Bash lo intercepta, lo reemplaza por "ls -l" , y ejecuta éste en su lugar. No hay ningún programa llamado ll en el sistema, pero el shell automáticamente traduce el alias a un programa válido.
Hay algunos alias de ejemplo en la figura 9.1.3. Puede ponerlos en su propio .bashrc. Uno especialmente interesante es el primero. Con él, cada vez que alguien teclea "ls" , automaticamente tiene una opción "-F" añadida. (El alias no intenta expandirse a sí mismo otra vez). Este es un modo muy común de añadir opciones que se usan constantemente al llamar a un programa.
Nótese los comentarios con el caracter "#" en la figura 9.1.3. Cada vez que aparece un "#", el shell ignora el resto de la línea.
Quizá haya notado unas cuantas cosas sueltas sobre los ejemplos. Primero, me he dejado las comillas en algunos de los alias como pu. Estrictamente hablando, las comillas no son necesarias cuando sólo se tiene una palabra a la derecha del signo igual.
Figura 9.1 Algunos alias de ejemplo para bash.
|| Alias || Comentario ||
|| alias ls="ls -F" alias ll="ls -l" alias la="ls -a" alias ro="rm *~; rm .*~" alias rd="rmdir" alias md="mkdir" alias pu=pushd alias po=popd alias ds=dirs || # muestra los caracteres al final del listado # ls especial # este borra las copias de seguridad creadas por Emacs # ahorra teclas! # pushd, popd, y dirs no estan incluidos en este # manual
quiza quiera echarles un vistazo # en la pagina man de Bash ||
|| alias to="telnet cs.oberlin.edu" alias ta="telnet altair.mcs.anl.gov" alias tg="telnet wombat.gnu.ai.mit.edu" alias tko="tpalk kold@cs.oberlin.edu" alias tjo="talk jimb@cs.oberlin.edu" alias mroe="more" alias moer="more" alias email="emacs -f rmail" alias ed2="emacs -d floss:0 -fg grey95 -bg grey50" || # estos solo son atajos de teclado # correcion ortografica! # mi lector de correo # asi llamo a Emacs ||
Pero no hace daño poner comillas, así que no me dejéis crearos malos hábitos. Ciertamente habrá que usarlas si se va a crear un alias de un comando con opciones y/o argumentos:
alias rf="refrobnicate -verbose -prolix -wordy -o foo.out"
Además, el último alias tiene algún entrecomillado gracioso:
alias ed2="emacs -d floss:0 -fg grey95 -bg grey50"
Como es fácil suponer, he querido pasar entrecomillados dentro de las opciones, así que tengo que anteponerles una contrabarra para que bash no crea que ya ha llegado al final del alias.
Finalmente, he creado dos alias de dos errores de escritura comunes, "mroe" y "moer", apuntando al comando que pretendía escribir, more. Los alias no interfieren con el paso de argumentos a un programa. Lo siguiente funciona bien:
/home/larry$ mroe hurd.txt
De hecho, saber como crear sus propios alias es probablemente por lo menos la mitad de las personalizaciones que hará jamás. Experimente un poco, descubra cuáles son los comandos largos que teclea frecuentemente, y cree alias para ellos. De esta manera, le resultará más confortable trabajar con el prompt del shell.
Variables de entorno
Otra cosa que uno hace frecuentemente en .bashrc es definir variables de entorno. Y >qué son las variables de entorno? Vamos a mirarlo desde otra dirección: Supongamos que está leyendo la documentación del programa fruggle, y se encuentra con una de estas expresiones:
Fruggle normalmente busca su fichero de configuración, .frugglerc, en el directorio raíz del usuario. Sin embargo si la variable de entorno FRUGGLEPATH indica un nombre de archivo diferente, mirará ahí en su lugar.
Cada programa se ejecuta en un entorno, y ese entorno es definido por el shell que llamó al programa1. Se puede decir que el entorno existe "dentro" del shell. Los programadores tienen una rutina especial para interrogar al entorno, y el programa fruggle usa esa rutina. Comprueba el valor de la variable de entorno FRUGGLEPATH. Si esa variable no está definida, sencillamente usará el archivo .frugglerc del directorio raíz. Si está definida, usará el valor de esa variable (que debe ser el nombre de un archivo que fruggle pueda usar) en lugar del archivo por defecto .frugglerc. Así es como se puede cambiar el entorno en bash:
/home/larry$ export PGPPATH=/home/larry/secrets/pgp
Hay que pensar en el comando export con este significado: "Por favor exporta esta variable fuera del entorno donde estaré llamando programas, de modo que su valor sea visible para ellos." Realmente hay razones para llamarlo export, como se verá después.
Esta variable en particular es usada por el infame programa de encriptación mediante clave pública de Phil Zimmerman, pgp. Por defecto, pgp usa el directorio raíz como lugar para encontrar determinados archivos que necesita (que contienen claves de encriptación), y también un lugar para guardar archivos temporales que crea mientras está en marcha. Al darle este valor a la variable PGPPATH, le he dicho que use el directorio /home/larry/secrets/pgp en lugar de /home/larry.
He tenido que leer el manual de pgp para encontrar el nombre exacto de la variable y lo que hace, pero es bastante estándar el uso del nombre del programa en mayúsculas, seguido del sufijo "PATH". También es útil saber como preguntar al entorno:
/home/larry$ echo $PGPPATH
/home/larry/.pgp
/home/larry$
Nótese el "$"; se precede la variable de entorno con un signo de dólar para extraer el valor de la variable. Si lo hubiera escrito sin el signo de dólar, echo simplemente habría mostrado su(s) argumento(s):
/home/larry$ echo PGPPATH
PGPPATH
/home/larry$
El "$" se usa para evaluar variables de entorno, pero sólo lo hace dentro del contexto del shell, o sea, cuando el shell está interpretando. ¿Cuando está el shell interpretando? Bueno, cuando se escriben comandos en el prompt, o cuando bash está leyendo comandos de un archivo como .bashrc, se puede decir que está "interpretando" los comandos.
_
1 Ahora se puede comprobar porqué los shells son tan importantes. <No hay que andar pasando un entorno completo a mano cada vez que se llame a un programa
Figura 9.2 Algunas variables de entorno importantes.
|| Nombre || Contenido || Ejemplo ||
|| HOME || Directorio principal del usuario || /home/larry ||
|| TERM || Tipo de terminal del usuario || xterm, vt100, o console ||
|| SHELL || Path del shell del usuario || /bin/bash ||
|| USER || Nombre de ingreso || larry ||
|| PATH || Lista de búsqueda de programas || /bin:/usr/bin:/usr/local/bin:/usr/bin/X11 ||
Hay otro comando muy útil para preguntar al entorno: env". env enseñará un listado de todas las variables de entorno. Es posible, especialmente si se usa X, que la lista se salga de la pantalla.
Si esto ocurre, hay que canalizar env a través de more: "env _ more".
Unas cuantas de estas variables pueden ser muy útiles, así que las comentaremos. Mire la Figura 9.1.4. Estas cuatro variables están definidas automáticamente cuando se ingresa en el sistema: no se definen en .bashrc o .bash_login.
Vamos a echar un vistazo más de cerca a la variable TERM. Para comprenderla, vamos a mirar hacia atrás en la historia del Unix: El sistema operativo necesita conocer ciertos datos sobre su consola para poder realizar funciones básicas, como escribir un carácter en la pantalla, mover el cursor a la línea siguiente, etc. En los primeros días de los ordenadores, los fabricantes estaban continuamente añadiendo nuevas características a sus terminales: primero el vídeo inverso, luego quizás juegos de caracteres europeos, eventualmente incluso primitivas funciones de dibujo (hay que recordar que éstos eran los tiempos anteriores a los sistemas de ventanas y el ratón). Pero todas estas funciones representaban un problema para los programadores: ¿Cómo iban a saber lo que un terminal podía soportar y lo que no? Y ¿cómo podían emplear nuevas características sin convertir los viejos terminales en inservibles?
En Unix, la respuesta a estas cuestiones fue /etc/termcap . /etc/termcap es una lista de todos los terminales que un sistema conoce, y como controlan el cursor. Si un administrador de sistema consigue un terminal nuevo, todo lo que tiene que hacer es añadir una entrada para ese terminal en /etc/termcap en lugar de recompilar todo el Unix. A veces es incluso más simple. Al pasar el tiempo, el vt100 de Digital Equipment Corporation se convirtió en un pseudo-estándar, y muchos nuevos terminales fueron construidos para que pudieran emularlo, o comportarse como si fueran un vt100.
Bajo Linux, el valor de TERM es a veces console, un clónico de vt-100 con algunas características añadidas.
Otra variable, PATH, es también crucial para el funcionamiento correcto del shell. Aquí está la mía:
/home/larry$ env _ grep ^PATH
PATH=/home/larry/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
/home/larry$
El PATH es una lista, separada por el carácter dos puntos ":", de los directorios donde el shell buscará el nombre del programa a ejecutar. Cuando yo tecleo "ls" y pulso |_Intro_|, por ejemplo, Bash primero busca en /home/larry/bin, un directorio que he hecho para guardar los programas que escribo. Pero yo no he escrito ls (de hecho, ¡creo que se escribió antes de que yo naciera!). Como no lo encuentra en /home/larry/bin, Bash mira después en /bin ¡y ahí hay una coincidencia! /bin/ls existe y es ejecutable, de modo que Bash deja de buscar un programa llamado ls y lo arranca. Podría haber habido perfectamente otro ls esperando en el directorio /usr/bin, pero bash nunca lo ejecutará si no lo pido especificando una ruta de directorios explícita:
/home/larry$ /usr/bin/ls
La variable PATH existe para no tener que teclear rutas de directorio completas para cada comando. Cuando se escribe un comando, Bash lo busca en los directorios nombrados en el PATH, en orden, y si lo encuentra, lo ejecuta. Si no lo encuentra, devuelve un descortés mensaje de error:
/home/larry$ clubly
clubly: command not found
Notar que en mi PATH no existe el directorio actual, ".". Si estuviera, tendría este aspecto:
/home/larry$ echo $PATH
.:/home/larry/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
/home/larry$
Esto es asunto de debate en los círculos de Unix (de los cuales ahora es miembro, le guste o no). El problema es que tener el directorio actual en el path puede ser un agujero en la seguridad. Supongamos que entramos en un directorio en el que alguien ha dejado un "Caballo de Troya" llamado ls, y hacemos un ls, como es natural después de entrar en un directorio nuevo. Como el directorio actual, ".", viene primero en nuestro PATH, el shell encontrará esta versión de ls y la ejecutará. Sea cual sea el daño que hayan puesto en ese programa, lo acabamos de activar (y puede ser un montón de daño). Quien fuera no necesita permisos de root para hacerlo; sólo hace falta permisos de escritura en el directorio donde se encuentra el "falso" ls. Incluso podría ser su propio directorio home, si sabe que vamos a estar husmeando por ahí en algún momento.
En su propio sistema, es muy improbable que las personas se estén dejando trampas unas a otras. Pero en un gran sistema multiusuario (como muchos ordenadores de universidades), hay un montón de programadores hostiles con los que nunca se ha encontrado. Que quiera tentar a la suerte o no teniendo "." en el path depende de la situación; no voy a ser dogmático en ningún sentido, sólo quiero informar de los riesgos implícitos2. Los sistemas multiusuario son verdaderas comunidades, donde la gente puede hacerles cosas a los demás en todo tipo de maneras nunca vistas.
El modo en que he dejado mi PATH incluye la mayoría de lo que se ha aprendido hasta ahora sobre variables de entorno. Esto es lo que hay actualmente en mi .bashrc:
export PATH=$-PATH":.:$-HOME"/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
_
2 Recuérdese que siempre se puede ejecutar un programa en el directorio actual siendo explícito, p.ej.: "./foo".
Me aprovecho de que la variable HOME se activa antes de que Bash lea el fichero .bashrc, usando su valor en la construcción del PATH. Las llaves ("{...}") son un nivel añadido de cita; delimitan el tamaño de lo que va a evaluar "$", de modo que el shell no se confunda por culpa del texto inmediatamente posterior ("/bin" en este caso). Aquí hay otro ejemplo del efecto que tienen:
/home/larry$ echo $-HOME"foo
/home/larryfoo
/home/larry$
Sin las llaves, no connseguiría nada, porque no hay ninguna variable de entorno llamada HOMEfoo.
/home/larry$ echo $HOMEfoo
/home/larry$
Quisiera aclarar una cosa en este path: el significado de "$PATH". Lo que hace es incluir el valor de cualquier variable PATH previamente activada en mi nuevo PATH. ¿Dónde se habrá activado la variable anterior? El archivo /etc/profile sirve como una especie de .bash_profile global, común a todos los usuarios. Tener un archivo centralizado como este hace más sencillo para el administrador del sistema añadir un directorio nuevo al PATH de todo el mundo, sin que cada uno tenga que hacerlo individualmente. Si se incluye el path antiguo en el nuevo, no se perderán ninguno de los directorios que el sistema ya haya preparado.
También se puede controlar como aparece el prompt. Esto se consigue mediante la variable de entorno PS1. Personalmente, quiero un prompt que me indique el path del directorio actual así es "como lo hago en mi .bashrc:
export PS1='$PWD"$ '
Como se puede ver, en realidad se usan dos variables. La que se activa es PS1, y toma el valor de PWD, que puede ser interpretada como "Print Working Directory" (imprime el directorio de trabajo) o "Path to Working Directory"(trayectoria al directorio de trabajo). Pero la evaluación de PWD tiene lugar entre apóstrofos agudos. Estos apóstrofos sirven para evaluar la expresión en su interior, la cual a su vez evalúa la variable PWD. Si sólo hubiéramos hecho "export PS1=$PWD" , nuestro prompt nos habría mostrado constantemente el path del directorio de trabajo en el momento en que PS1 fue activada, en lugar de actualizarse constantemente mientras cambiamos de directorios. Bueno, es un poco confuso, y no muy importante en realidad. Sólo hay que tener en cuenta que se necesita esa clase de apóstrofos si se quiere mostrar el directorio actual en el prompt.
Quizá se prefiera "export PS1='$PWD>'" , o incluso el nombre del sistema:
export PS1=`hostname`'>'
Diseccionemos este ejemplo un poco más. Aquí se usa un nuevo tipo de literal, el apóstrofo grave. Esta clase de literal no protege nada, de hecho, 'hostname' no aparece en ninguna parte del prompt cuando intentamos arrancarlo. Lo que sucede realmente es que se evalúa el comando dentro de los apóstrofos graves, y el resultado se guarda en lugar del nombre del comando entrecomillado.
Probemos con "echo `ls`" o "wc `ls`" . A medida que se consiga más experiencia usando el shell, esta técnica se hace más y más potente.
Hay mucho más por comentar de como se configura el fichero .bashrc, y aquí no hay bastante espacio para hacerlo. Se puede aprender más leyendo la página man de bash, o preguntando a usuarios experimentados. Aquí hay un .bashrc completo para poder estudiarlo; es razonablemente estándar, aunque el path es un poco largo.
# Algunas cosas al azar:
ulimit -c unlimited
export history_control=ignoredups
export PS1='$PWD>'
umask 022
# paths específicos de aplicaciones:
export MANPATH=/usr/local/man:/usr/man
export INFOPATH=/usr/local/info
export PGPPATH=$-HOME"/.pgp
# PATH principal:
homepath=$-HOME":~/bin
stdpath=/bin:/usr/bin:/usr/local/bin:/usr/ucb/:/etc:/usr/etc:/usr/games
pubpath=/usr/public/bin:/usr/gnusoft/bin:/usr/local/contribs/bin
softpath=/usr/bin/X11:/usr/local/bin/X11:/usr/TeX/bin
export PATH=.:$-homepath":$-stdpath":$-pubpath":$-softpath"
# Técnicamente, las llaves no eran necesarias, porque los dos puntos son
# delimitadores válidos; pero las llaves son una buena costumbre,
# y no hacen daño.
# alias
alias ls="ls -CF"
alias fg1="fg %1"
alias fg2="fg %2"
alias tba="talk sussman@tern.mcs.anl.gov"
alias tko="talk kold@cs.oberlin.edu"
alias tji="talk jimb@totoro.bio.indiana.edu"
alias mroe="more"
alias moer="more"
alias email="emacs -f vm"
alias pu=pushd
alias po=popd
alias b="~/.b"
alias ds=dirs
alias ro="rm *~; rm .*~"
alias rd="rmdir"
alias ll="ls -l"
alias la="ls -a"
alias rr="rm -r"
alias md="mkdir"
alias ed2="emacs -d floss:0 -fg grey95 -bg grey50"
function gco
-
gcc -o $1 $1.c -g
"
Los ficheros de configuración más importantes son los usados por el shell. El shell por defecto de Linux es el bash, y éste es el shell que cubre este capítulo. Antes de empezar a explicar cómo personalizar el bash, tenemos que saber cuales son los archivos que mira.
Arranque del shell
Hay diferentes modos de funcionamiento del bash. Puede funcionar como shell de ingreso, que es el modo en que arranca cuando se ingresa por primera vez. El shell de ingreso debería ser el primer shell que vea.
Otro modo en que puede funcionar bash es como shell interactivo. Este es un shell que presenta un prompt a un humano y espera una entrada de datos. Un shell de ingreso también es un shell interactivo. Una manera de conseguir un shell interactivo sin ingresar en el sistema es, por ejemplo, un shell dentro de xterm. Cualquier shell que sea creado por otro medio distinto del ingreso registrado en el sistema es un shell de no-ingreso.
Finalmente, hay shells no interactivos. Estos shells se usan para ejecutar un archivo de comandos, muy parecidos a los ficheros de procesamiento por lotes del MS-DOS, los archivos que acaban en .BAT. Estas macros de shell funcionan como mini-programas. Aunque son usualmente mucho más lentos que un programa normal compilado, suele ser cierto también que son mucho más fáciles de escribir. Dependiendo del tipo de shell, se usarán distintos tipos de archivo al arrancarlo:
|| Tipo de Shell || Acción ||
|| Ingreso interactivo || Se lee y ejecuta el archivo .bash_profile ||
|| Interactivo || Se lee y ejecuta el archivo .bashrc ||
|| No_interactivo || Se lee y ejecuta la macro de shell ||
Ficheros de arranque
Como muchos usuarios quieren tener mayormente el mismo entorno, sin importar que tipo de shell interactivo acaben teniendo, y sea o no un shell de ingreso, empezaremos nuestra configuración poniendo un comando muy simple en nuestro archivo .bash_profile: "source ~/.bashrc". El comando source ordena al shell que interprete el argumento como una macro de shell. Lo que significa para nosotros es que cada vez que .bash_profile se ejecuta, también se ejecuta .bashrc. Ahora, sólo añadiremos comandos a nuestro archivo .bashrc. Si alguna vez queremos que se ejecute un comando únicamente cuando hemos hecho un ingreso registrado, lo añadiremos a nuestro .bash_profile.
Creando alias
¿Cuales son algunas de las cosas que interesaría personalizar? Esto es algo que creo que el 90% de los usuarios de Bash han puesto en su .bashrc:
alias ll="ls -l"
Este comando define un alias de shell llamado ll que "expande" el comando normal de shell "ls -l" cuando se invoca por el usuario. De modo que, asumiendo que Bash ha leído este comando del fichero .bashrc, podemos teclear ll para conseguir el efecto de "ls-l"_ con solo la mitad de pulsaciones. Lo que ocurre es que cuando tecleamos "ll" y pulsamos |_Intro_|, Bash lo intercepta, lo reemplaza por "ls -l" , y ejecuta éste en su lugar. No hay ningún programa llamado ll en el sistema, pero el shell automáticamente traduce el alias a un programa válido.
Hay algunos alias de ejemplo en la figura 9.1.3. Puede ponerlos en su propio .bashrc. Uno especialmente interesante es el primero. Con él, cada vez que alguien teclea "ls" , automaticamente tiene una opción "-F" añadida. (El alias no intenta expandirse a sí mismo otra vez). Este es un modo muy común de añadir opciones que se usan constantemente al llamar a un programa.
Nótese los comentarios con el caracter "#" en la figura 9.1.3. Cada vez que aparece un "#", el shell ignora el resto de la línea.
Quizá haya notado unas cuantas cosas sueltas sobre los ejemplos. Primero, me he dejado las comillas en algunos de los alias como pu. Estrictamente hablando, las comillas no son necesarias cuando sólo se tiene una palabra a la derecha del signo igual.
Figura 9.1 Algunos alias de ejemplo para bash.
|| Alias || Comentario ||
|| alias ls="ls -F" alias ll="ls -l" alias la="ls -a" alias ro="rm *~; rm .*~" alias rd="rmdir" alias md="mkdir" alias pu=pushd alias po=popd alias ds=dirs || # muestra los caracteres al final del listado # ls especial # este borra las copias de seguridad creadas por Emacs # ahorra teclas! # pushd, popd, y dirs no estan incluidos en este # manual
quiza quiera echarles un vistazo # en la pagina man de Bash ||
|| alias to="telnet cs.oberlin.edu" alias ta="telnet altair.mcs.anl.gov" alias tg="telnet wombat.gnu.ai.mit.edu" alias tko="tpalk kold@cs.oberlin.edu" alias tjo="talk jimb@cs.oberlin.edu" alias mroe="more" alias moer="more" alias email="emacs -f rmail" alias ed2="emacs -d floss:0 -fg grey95 -bg grey50" || # estos solo son atajos de teclado # correcion ortografica! # mi lector de correo # asi llamo a Emacs ||
Pero no hace daño poner comillas, así que no me dejéis crearos malos hábitos. Ciertamente habrá que usarlas si se va a crear un alias de un comando con opciones y/o argumentos:
alias rf="refrobnicate -verbose -prolix -wordy -o foo.out"
Además, el último alias tiene algún entrecomillado gracioso:
alias ed2="emacs -d floss:0 -fg grey95 -bg grey50"
Como es fácil suponer, he querido pasar entrecomillados dentro de las opciones, así que tengo que anteponerles una contrabarra para que bash no crea que ya ha llegado al final del alias.
Finalmente, he creado dos alias de dos errores de escritura comunes, "mroe" y "moer", apuntando al comando que pretendía escribir, more. Los alias no interfieren con el paso de argumentos a un programa. Lo siguiente funciona bien:
/home/larry$ mroe hurd.txt
De hecho, saber como crear sus propios alias es probablemente por lo menos la mitad de las personalizaciones que hará jamás. Experimente un poco, descubra cuáles son los comandos largos que teclea frecuentemente, y cree alias para ellos. De esta manera, le resultará más confortable trabajar con el prompt del shell.
Variables de entorno
Otra cosa que uno hace frecuentemente en .bashrc es definir variables de entorno. Y >qué son las variables de entorno? Vamos a mirarlo desde otra dirección: Supongamos que está leyendo la documentación del programa fruggle, y se encuentra con una de estas expresiones:
Fruggle normalmente busca su fichero de configuración, .frugglerc, en el directorio raíz del usuario. Sin embargo si la variable de entorno FRUGGLEPATH indica un nombre de archivo diferente, mirará ahí en su lugar.
Cada programa se ejecuta en un entorno, y ese entorno es definido por el shell que llamó al programa1. Se puede decir que el entorno existe "dentro" del shell. Los programadores tienen una rutina especial para interrogar al entorno, y el programa fruggle usa esa rutina. Comprueba el valor de la variable de entorno FRUGGLEPATH. Si esa variable no está definida, sencillamente usará el archivo .frugglerc del directorio raíz. Si está definida, usará el valor de esa variable (que debe ser el nombre de un archivo que fruggle pueda usar) en lugar del archivo por defecto .frugglerc. Así es como se puede cambiar el entorno en bash:
/home/larry$ export PGPPATH=/home/larry/secrets/pgp
Hay que pensar en el comando export con este significado: "Por favor exporta esta variable fuera del entorno donde estaré llamando programas, de modo que su valor sea visible para ellos." Realmente hay razones para llamarlo export, como se verá después.
Esta variable en particular es usada por el infame programa de encriptación mediante clave pública de Phil Zimmerman, pgp. Por defecto, pgp usa el directorio raíz como lugar para encontrar determinados archivos que necesita (que contienen claves de encriptación), y también un lugar para guardar archivos temporales que crea mientras está en marcha. Al darle este valor a la variable PGPPATH, le he dicho que use el directorio /home/larry/secrets/pgp en lugar de /home/larry.
He tenido que leer el manual de pgp para encontrar el nombre exacto de la variable y lo que hace, pero es bastante estándar el uso del nombre del programa en mayúsculas, seguido del sufijo "PATH". También es útil saber como preguntar al entorno:
/home/larry$ echo $PGPPATH
/home/larry/.pgp
/home/larry$
Nótese el "$"; se precede la variable de entorno con un signo de dólar para extraer el valor de la variable. Si lo hubiera escrito sin el signo de dólar, echo simplemente habría mostrado su(s) argumento(s):
/home/larry$ echo PGPPATH
PGPPATH
/home/larry$
El "$" se usa para evaluar variables de entorno, pero sólo lo hace dentro del contexto del shell, o sea, cuando el shell está interpretando. ¿Cuando está el shell interpretando? Bueno, cuando se escriben comandos en el prompt, o cuando bash está leyendo comandos de un archivo como .bashrc, se puede decir que está "interpretando" los comandos.
_
1 Ahora se puede comprobar porqué los shells son tan importantes. <No hay que andar pasando un entorno completo a mano cada vez que se llame a un programa
Figura 9.2 Algunas variables de entorno importantes.
|| Nombre || Contenido || Ejemplo ||
|| HOME || Directorio principal del usuario || /home/larry ||
|| TERM || Tipo de terminal del usuario || xterm, vt100, o console ||
|| SHELL || Path del shell del usuario || /bin/bash ||
|| USER || Nombre de ingreso || larry ||
|| PATH || Lista de búsqueda de programas || /bin:/usr/bin:/usr/local/bin:/usr/bin/X11 ||
Hay otro comando muy útil para preguntar al entorno: env". env enseñará un listado de todas las variables de entorno. Es posible, especialmente si se usa X, que la lista se salga de la pantalla.
Si esto ocurre, hay que canalizar env a través de more: "env _ more".
Unas cuantas de estas variables pueden ser muy útiles, así que las comentaremos. Mire la Figura 9.1.4. Estas cuatro variables están definidas automáticamente cuando se ingresa en el sistema: no se definen en .bashrc o .bash_login.
Vamos a echar un vistazo más de cerca a la variable TERM. Para comprenderla, vamos a mirar hacia atrás en la historia del Unix: El sistema operativo necesita conocer ciertos datos sobre su consola para poder realizar funciones básicas, como escribir un carácter en la pantalla, mover el cursor a la línea siguiente, etc. En los primeros días de los ordenadores, los fabricantes estaban continuamente añadiendo nuevas características a sus terminales: primero el vídeo inverso, luego quizás juegos de caracteres europeos, eventualmente incluso primitivas funciones de dibujo (hay que recordar que éstos eran los tiempos anteriores a los sistemas de ventanas y el ratón). Pero todas estas funciones representaban un problema para los programadores: ¿Cómo iban a saber lo que un terminal podía soportar y lo que no? Y ¿cómo podían emplear nuevas características sin convertir los viejos terminales en inservibles?
En Unix, la respuesta a estas cuestiones fue /etc/termcap . /etc/termcap es una lista de todos los terminales que un sistema conoce, y como controlan el cursor. Si un administrador de sistema consigue un terminal nuevo, todo lo que tiene que hacer es añadir una entrada para ese terminal en /etc/termcap en lugar de recompilar todo el Unix. A veces es incluso más simple. Al pasar el tiempo, el vt100 de Digital Equipment Corporation se convirtió en un pseudo-estándar, y muchos nuevos terminales fueron construidos para que pudieran emularlo, o comportarse como si fueran un vt100.
Bajo Linux, el valor de TERM es a veces console, un clónico de vt-100 con algunas características añadidas.
Otra variable, PATH, es también crucial para el funcionamiento correcto del shell. Aquí está la mía:
/home/larry$ env _ grep ^PATH
PATH=/home/larry/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
/home/larry$
El PATH es una lista, separada por el carácter dos puntos ":", de los directorios donde el shell buscará el nombre del programa a ejecutar. Cuando yo tecleo "ls" y pulso |_Intro_|, por ejemplo, Bash primero busca en /home/larry/bin, un directorio que he hecho para guardar los programas que escribo. Pero yo no he escrito ls (de hecho, ¡creo que se escribió antes de que yo naciera!). Como no lo encuentra en /home/larry/bin, Bash mira después en /bin ¡y ahí hay una coincidencia! /bin/ls existe y es ejecutable, de modo que Bash deja de buscar un programa llamado ls y lo arranca. Podría haber habido perfectamente otro ls esperando en el directorio /usr/bin, pero bash nunca lo ejecutará si no lo pido especificando una ruta de directorios explícita:
/home/larry$ /usr/bin/ls
La variable PATH existe para no tener que teclear rutas de directorio completas para cada comando. Cuando se escribe un comando, Bash lo busca en los directorios nombrados en el PATH, en orden, y si lo encuentra, lo ejecuta. Si no lo encuentra, devuelve un descortés mensaje de error:
/home/larry$ clubly
clubly: command not found
Notar que en mi PATH no existe el directorio actual, ".". Si estuviera, tendría este aspecto:
/home/larry$ echo $PATH
.:/home/larry/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
/home/larry$
Esto es asunto de debate en los círculos de Unix (de los cuales ahora es miembro, le guste o no). El problema es que tener el directorio actual en el path puede ser un agujero en la seguridad. Supongamos que entramos en un directorio en el que alguien ha dejado un "Caballo de Troya" llamado ls, y hacemos un ls, como es natural después de entrar en un directorio nuevo. Como el directorio actual, ".", viene primero en nuestro PATH, el shell encontrará esta versión de ls y la ejecutará. Sea cual sea el daño que hayan puesto en ese programa, lo acabamos de activar (y puede ser un montón de daño). Quien fuera no necesita permisos de root para hacerlo; sólo hace falta permisos de escritura en el directorio donde se encuentra el "falso" ls. Incluso podría ser su propio directorio home, si sabe que vamos a estar husmeando por ahí en algún momento.
En su propio sistema, es muy improbable que las personas se estén dejando trampas unas a otras. Pero en un gran sistema multiusuario (como muchos ordenadores de universidades), hay un montón de programadores hostiles con los que nunca se ha encontrado. Que quiera tentar a la suerte o no teniendo "." en el path depende de la situación; no voy a ser dogmático en ningún sentido, sólo quiero informar de los riesgos implícitos2. Los sistemas multiusuario son verdaderas comunidades, donde la gente puede hacerles cosas a los demás en todo tipo de maneras nunca vistas.
El modo en que he dejado mi PATH incluye la mayoría de lo que se ha aprendido hasta ahora sobre variables de entorno. Esto es lo que hay actualmente en mi .bashrc:
export PATH=$-PATH":.:$-HOME"/bin:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/TeX/bin
_
2 Recuérdese que siempre se puede ejecutar un programa en el directorio actual siendo explícito, p.ej.: "./foo".
Me aprovecho de que la variable HOME se activa antes de que Bash lea el fichero .bashrc, usando su valor en la construcción del PATH. Las llaves ("{...}") son un nivel añadido de cita; delimitan el tamaño de lo que va a evaluar "$", de modo que el shell no se confunda por culpa del texto inmediatamente posterior ("/bin" en este caso). Aquí hay otro ejemplo del efecto que tienen:
/home/larry$ echo $-HOME"foo
/home/larryfoo
/home/larry$
Sin las llaves, no connseguiría nada, porque no hay ninguna variable de entorno llamada HOMEfoo.
/home/larry$ echo $HOMEfoo
/home/larry$
Quisiera aclarar una cosa en este path: el significado de "$PATH". Lo que hace es incluir el valor de cualquier variable PATH previamente activada en mi nuevo PATH. ¿Dónde se habrá activado la variable anterior? El archivo /etc/profile sirve como una especie de .bash_profile global, común a todos los usuarios. Tener un archivo centralizado como este hace más sencillo para el administrador del sistema añadir un directorio nuevo al PATH de todo el mundo, sin que cada uno tenga que hacerlo individualmente. Si se incluye el path antiguo en el nuevo, no se perderán ninguno de los directorios que el sistema ya haya preparado.
También se puede controlar como aparece el prompt. Esto se consigue mediante la variable de entorno PS1. Personalmente, quiero un prompt que me indique el path del directorio actual así es "como lo hago en mi .bashrc:
export PS1='$PWD"$ '
Como se puede ver, en realidad se usan dos variables. La que se activa es PS1, y toma el valor de PWD, que puede ser interpretada como "Print Working Directory" (imprime el directorio de trabajo) o "Path to Working Directory"(trayectoria al directorio de trabajo). Pero la evaluación de PWD tiene lugar entre apóstrofos agudos. Estos apóstrofos sirven para evaluar la expresión en su interior, la cual a su vez evalúa la variable PWD. Si sólo hubiéramos hecho "export PS1=$PWD" , nuestro prompt nos habría mostrado constantemente el path del directorio de trabajo en el momento en que PS1 fue activada, en lugar de actualizarse constantemente mientras cambiamos de directorios. Bueno, es un poco confuso, y no muy importante en realidad. Sólo hay que tener en cuenta que se necesita esa clase de apóstrofos si se quiere mostrar el directorio actual en el prompt.
Quizá se prefiera "export PS1='$PWD>'" , o incluso el nombre del sistema:
export PS1=`hostname`'>'
Diseccionemos este ejemplo un poco más. Aquí se usa un nuevo tipo de literal, el apóstrofo grave. Esta clase de literal no protege nada, de hecho, 'hostname' no aparece en ninguna parte del prompt cuando intentamos arrancarlo. Lo que sucede realmente es que se evalúa el comando dentro de los apóstrofos graves, y el resultado se guarda en lugar del nombre del comando entrecomillado.
Probemos con "echo `ls`" o "wc `ls`" . A medida que se consiga más experiencia usando el shell, esta técnica se hace más y más potente.
Hay mucho más por comentar de como se configura el fichero .bashrc, y aquí no hay bastante espacio para hacerlo. Se puede aprender más leyendo la página man de bash, o preguntando a usuarios experimentados. Aquí hay un .bashrc completo para poder estudiarlo; es razonablemente estándar, aunque el path es un poco largo.
# Algunas cosas al azar:
ulimit -c unlimited
export history_control=ignoredups
export PS1='$PWD>'
umask 022
# paths específicos de aplicaciones:
export MANPATH=/usr/local/man:/usr/man
export INFOPATH=/usr/local/info
export PGPPATH=$-HOME"/.pgp
# PATH principal:
homepath=$-HOME":~/bin
stdpath=/bin:/usr/bin:/usr/local/bin:/usr/ucb/:/etc:/usr/etc:/usr/games
pubpath=/usr/public/bin:/usr/gnusoft/bin:/usr/local/contribs/bin
softpath=/usr/bin/X11:/usr/local/bin/X11:/usr/TeX/bin
export PATH=.:$-homepath":$-stdpath":$-pubpath":$-softpath"
# Técnicamente, las llaves no eran necesarias, porque los dos puntos son
# delimitadores válidos; pero las llaves son una buena costumbre,
# y no hacen daño.
# alias
alias ls="ls -CF"
alias fg1="fg %1"
alias fg2="fg %2"
alias tba="talk sussman@tern.mcs.anl.gov"
alias tko="talk kold@cs.oberlin.edu"
alias tji="talk jimb@totoro.bio.indiana.edu"
alias mroe="more"
alias moer="more"
alias email="emacs -f vm"
alias pu=pushd
alias po=popd
alias b="~/.b"
alias ds=dirs
alias ro="rm *~; rm .*~"
alias rd="rmdir"
alias ll="ls -l"
alias la="ls -a"
alias rr="rm -r"
alias md="mkdir"
alias ed2="emacs -d floss:0 -fg grey95 -bg grey50"
function gco
-
gcc -o $1 $1.c -g
"
Valora este capítulo:
Autor y licencia de 'Personalización del bash - Personalización del bash'
|
Opiniona sobre 'Personalización del bash - Personalización del bash' (0)
Tu nombre debe tener tres caracteres como mínimo.
Es necesario que te des de alta con una cuenta de correo válida.
Es necesario que te des de alta con una cuenta de correo válida.
El contenido del título de tu opinión debe tener tres caracteres como mínimo.
Es obligatorio que selecciones una valoración del recurso.
El contenido del comentario de tu opinión debe tener tres caracteres como mínimo.
Opina sobre este tutorial |
Wikis relacionados con 'Personalización del bash - Personalización del bash'
Este artículo pretende ayudarle a comenzar a programar shell scripts a un nivel básico/intermedio. No...
Más »
Se comenta la creación y el manejo de prompts de terminales en modo texto y...
Más »
No conocerás lo que es Linux hasta que no conozcas la consola . La consola...
Más »
Aún cuando actualmente se puede manejar Linux de una manera tan gráfica como Windows, siempre...
Más »
Una de las cosas que distinguen la filosofía de Unix es que los diseñadores de...
Más »

