La línea de comandos. Ese gran desconocido.
Hoy estoy en uno de esos días ASCII. ¿Por qué no? Vamos a tunear, cual R5, la línea de comandos un poquito a ver qué nos pasa. En mi caso uso bash sobre Mac pero supongo que sobre linux y windows (en caso que useis cygwin) será todo exactamente igual así que nadie debería sentirse discriminado. Yo estoy aún en proceso de adaptar todo esto a Windows. Si tengo que hacer algo raro lo pondré aquí.
Hay mucha gente que hace estas cosas de preparar mucho su consola y luego ponerlo en internet. No teneis más que buscar “dotfiles” y vereis centenares de ejemplos.
Los ficheros de arranque
A poco que hayais toqueteado la línea de comandos sabreis que hay varios ficheros que lanzan automáticamente para nosotros varios comandos que podemos utilizar para personalizar nuestro entorno. Es el caso de .bashrc o .bash_profile . Personalmente siempre me había preguntado cual era la diferencia entre ellos pero nunca me había preocupado de mirarlo… hasta hoy.
- .bashrc: Se ejecuta cada vez que lanzamos bash. Es decir, cada vez que ejecutemos un script, cada vez que abramos una sesión ssh, cada vez que hagamos un login… Normalmente meteremos toda la configuración aquí.
- .bash_profile: Se ejecuta cada vez que iniciamos sesión interactiva. Normalmente, si existe, solo tendremos una línea que cargará el .bashrc así que tampoco nos tendremos que preocupar mucho.
Con esto ya tenemos bastante para juguetear con nuestro entorno. De todos modos yo prefiero crearme una carpeta /bin/.bash en mi carpeta home y poder separar en varios ficheros tranquilamente. Curiosamente en windows solo me deja crear una carpeta que empiece con punto desde la línea de comandos.
La estructura de ficheros
El caso es que así podemos separar en ficheros la configuración de nuestra consola y podemos dejarlo todo ordenadito. Vamos a hacer algo bastante simple:
Yo tengo esta estructura creada en mi carpeta home. Luego puedo hacer vínculos simbólicos a los archivos .bashrc y .bash_profile. Prefiero tenerlo todo en una carpeta porque intento tener todo metido en un control de versiones para mis distintas máquinas. Entonces tan solo tenemos que editar el bashrc de la carpeta .bash y añadir unas sencillas líneas para arrancar nuestro ecosistema.
Como el .bashrc solo se ejecuta cuando arrancamos la máquina conviene que el .bash_profile sencillamente lance el bashrc porque, particularmente, no necesito ninguna diferencia entre lanzar una shell o la configuración del sistema.
.bash_profile
if [ -f ~/.bashrc ]; then . ~/.bashrc fi
Y voy a hacer la primera advertencia escribiendo scripts de bash. El 99% de los errores que se suelen cometer son por falta de espacios en blanco. Por ejemplo, en el if, entre el corchete y el -f hay un espacio en blanco que es obligatorio.
Entonces en el bash_profile tan solo comprobamos si existe el bashrc para ejecutarlo después.
Con el punto estamos lanzando otro fichero. El punto es equivalente al comando “source“. Sencillamente nos permite organizarnos en varios ficheros por si tu script se alarga. Con el “-f” estamos comprobando si existe o no un fichero.
.bashrc
if [ $OSTYPE = 'darwin10.0' ]; then . ~/.bash/macEnv else if [ $OSTYPE = 'cygwin' ]; then . ~/.bash/winEnv fi fi . ~/.bash/config . ~/.bash/aliases
En las primeras líneas dependiendo del SO en el que estemos lanzaremos uno u otro script de variables de entorno. Algunas de las cosas que haremos son dependientes del sistema operativo. La más evidente es el tema de las rutas. Si utilizas muchas variables de entorno con rutas a lo mejor merece la pena crear varios ficheros env uno por operativo. Bash nos indica el tipo de sistema operativo en el que estamos con la variable OSTYPE. Habra multitud de ejemplos a lo largo de este post.
Dependiendo del caso puede que en lugar de diferenciar por el operativo te interese, personalmente, diferenciar por nombre de máquina. Como yo suelo guardar todo en el mismo sitio siempre me gusta más así.
La variables de entorno
Empezamos el juego. En nuestros ficheros env setearemos las variables de entorno. Por ejemplo el env de mi mac podría ser algo así.
envMac
export PATH=$PATH:/sw/bin:~/bin export EDITOR='mvim' export DROPBOXFOLDER='~/Dropbox'
Con esto tenemos asignadas las variables PATH y EDITOR. Por defecto, si asignamos una variable en un script de bash solo es accesible desde el entorno del script. Para que esta variable esté asignada de manera global utilizamos el comando export. Si usais svn desde linea de comandos, necesita que tengais una variable EDITOR definida que será el editor que se utilizará para editar los comentarios de los commits.
También tengo definida una variable con la ruta de mi Dropbox. Su uso lo vereis más adelante. En realidad tengo un montón de rutas más como por ejemplo la carpeta donde tengo el código fuente del trabajo o de alguno de mis proyectos pero tampoco merece la pena y lo omito para mantener esto lo más simple posible.
Los aliases
Aqui pondremos los aliases que definamos. Esta es una de las partes más interesantes y la que más trabajo nos va a ahorrar a la hora de trabajar con la consola. Como normalmente acabarás con 50.000 aliases definidos es mejor que tengan su propio fichero de configuración.
Vamos a empezar con lo básico. Hay comandos que lanzamos muchas veces así que nos interesa tener un shortcut que nos permita tener que teclear menos. Por ejemplo, si somos unos fanáticos de rails y estamos todo el día utilizando el comando rails porque hemos migrado a rails3 podemos añadir a nuestro aliases la línea.
alias r='rails'
Entonces cada vez que tecleemos “r” será como si pusiésemos rails.
Eso nos puede ahorrar tecleos. Hay mucha gente a la que le gusta poner “l” para ejecutar “ls”. Eso ya es cuestión de gustos.
Alias también está muy bien para forzar parámetros a ciertos comandos. Por ejemplo:
alias ls='ls -F'
Hará que siempre que se ejecute ls lo haga con el parámetro -F. Esto a mi no me suele convencer mucho porque luego si quieres quitarlo solamente una vez es un jaleo pero ahí está. Úsalo con cuidado.
Otra utilidad muy interesante y por la que empezó la idea de este post es la de poder cambiar de carpeta más rápidamente. Por ejemplo, y utilizando las variables que definimos en el fichero env, podemos hacer
alias cddropbox="cd $DROPBOXFOLDER"
Y puedo cambiar de carpeta a la carpeta de dropbox muy rápidamente desde la linea de comandos. Esto es muy útil cuando estamos trabajando en alguna ruta particular que tiene una ruta demasiado larga.
Los alias están bien pero las funciones ya son algo de otro mundo. Una función recibe parámetros y ejecuta una serie de comandos que pueden recibir los parámetros que le hemos pasado.
function lsView() {
ls -la $1 > $TMP/lsView.txt
$EDITOR $TMP/lsView.txt &
}
La configuración
Aqui añadiremos cosas como el prompt. Ya que nos ponemos vamos a dejarlo todo bonito.
El prompt de BASH se cambia con la variable de entorno PS1 asi que si queremos cambiar el prompt tan solo hay que cambiar esa variable. Por ejemplo:
export PS1="mi prompt es mío y hago con él lo que quiero: "
Nos dejaría con un estúpido e inútil a la vez que divertido prompt. Si queremos hacer algo más serio mejor que os paseis por el manual de bash ya que tienen una sección con los caracteres especiales que podemos utilizar. Por ejemplo:
export PS1="\w $ "
También se puede ejecutar un comando para rellenar el prompt. He visto gente que lo hace con su control de versiones para saber en la revision en la que está. Por ejemplo podríamos mostrar la carpeta actual con pwd haciendo:
export PS1="\$(pwd) $ "
Los códigos de colores los podemos encontrar en el BASH howto y son
Negro 0;30 Gris oscuro 1;30
Azul 0;34 Azul claro 1;34
Verde 0;32 Verde claro 1;32
Cyan 0;36 Cyan claro 1;36
Rojo 0;31 Rojo claro 1;31
Púrpura 0;35 Púrpura claro 1;35
Marrón 0;33 Amarillo 1;33
Gris claro 0;37 blanco 1;37
Para cambiar el color de la terminal hay que utlilzar la cadena \[\033[<codigocolor>m\] y una vez que terminemos de utilizar ese color devolverla a el código vacío: \[\033[0m\]
Para poner la terminar en verde, por ejemplo, utilizaremos
GREEN="\[\033[1;32m\]" RESET="\[\033[0m\]" PS1="$GREEN[\W]$RESET "
y tendremos un bello prompt
En lo simple está lo bello aunque se pueden hacer cosas bastante funky como por ejemplo:
GREEN="\[\033[1;32m\]" RESET="\[\033[0m\]" PS1="$GREEN[\W]$RESET - \h - \t \n->"
La version en dos líneas está bien si la combinas con Vcprompt. Eso ya es la repanocha. Vamos a poner que si estamos en un control de versiones (creo que solo soporta svn, mercurial y git) nos muestre la rama en la que estamos:
GREEN="\[\033[1;32m\]" RESET="\[\033[0m\]" CYAN="\[\033[1;36m\]" PS1="\t - $GREEN[\W]$RESET - $CYAN[\$(vcprompt)]$RESET - \h \n->"
Vemos que nos hemos pasado a una carpeta que es un repositorio de subversion de la rama trunk. Vereis que algunos screenshots de este post están con este prompt y es que después de escribir esto me he quedado con esta version tan … cutre y a la vez bella. Con esta shell me siento como si le acabase de poner spoilers y neones a un Skoda Fabia. Me apetece ponerme gorra y escuchar el Maquina Total 8.
Pues aquí lo dejo que ya llevo bastante tiempo escribiendo esto. Esperemos que con esto se te haga un poco más agradable los días sobre esa ya no tan aburrida terminal. Si con esto no ligas en la próxima reunion de la hermandad de la línea de comandos es que no tienes remedio.
Por último, y si os ha parecido interesante el post os recomiendo comprar el screencast de peepcode sobre advanced command line. Trabaja de una manera muy similar a la que he puesto aquí pero además añade un montón de consejos y sugerencias interesantísimas. Son unos 9 dólares que considero bien gastados.
Como no voy a ser menos he subido los dotfiles que he generado con esto a un repositorio de mercurial: https://bitbucket.org/rafadc/dotfiles
Supongo que iré actualizando ahí a medida que los vaya usando. ¡Me voy a buscar un cliente de twitter para línea de comandos!
Referencias:
[1] Manual de bash: http://www.gnu.org/software/bash/manual/bashref.html
[2] Peepcode: http://peepcode.com/
[3] Bash HOWTO: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html
[4] Vcprompt: http://github.com/xvzf/vcprompt











Mola
Me ha servido para una cosica que tenía que hacer en el ubuntu
Cojonudo gracias!