Sep 162007
 

Otras shells ¿Puedo elegir que shell uso?

Volvemos a remontarnos a la historia de UNIX (prometo que una vez pasada la introducción, no volveré a hacerlo), hablábamos en la entrega anterior del curso de que los primeros Unix de Bell y de AT&T incluían la shell sh de Bourne. Luego la historia de UNIX se bifurca desde el momento que las universidades solicitan utilizarlo y Bell les distribuye de forma abierta el código fuente. En Berkeley, comienza a gestarse BSD, BSD no usa la shell de Bourne, sino una cuyo lenguaje recuerda más a la sintaxis del lenguaje C llamada C-shell o csh. A David Korn de AT&T le gusta la sintaxis de c-shell y la mejora creando la Korn-shell o ksh. Simultáneamente la Free Software Foundation busca una shell para su sistema operativo GNU y tomando ideas de la shell de Bourne y de la Korn Shell crean Bash, ¡vaya! esta ya nos suena…

Paul Falstad por su parte cogiendo ideas de bash y de ksh crea otra shell llamada zsh. Hoy en día hay muchas shells donde elegir, sh, csh, tcsh, ksh, zsh… cada una tiene sus peculiaridades y sus ventajas, y en este curso nos centraremos en bash por ser la más usada en Linux, pero creo que era necesario citar las demás.

Un usuario de Linux normalmente puede elegir que shell utiliza, aunque como digo, por defecto suele tener la shell bash. Para cambiar de shell usaremos el comando chsh (change shell). Como sabes Linux (y Unix) es multiusuario. Cuando entramos en un UNIX o en un Linux lo normal es que el sistema nos pida un nombre de usuario y una clave, es lo que conocemos como login, el programa login comprueba que el usuario existe, y comprueba si la clave es correcta. Si lo es, mira en el fichero de configuración de usuario cual es la shell que el usuario tiene asignada, y la ejecuta.

La shell, un primer contacto

Vamos a hacer nuestras primeras pruebas con la shell, supongo que sabes abrir una shell, pero por si acaso lo explico:

Prueba a hacer login en una consola de texto de tu Linux. Si estás en un linux normalmente configurado en modo gráfico, te recuerdo que puedes ir a cualquiera de las 6 consolas de texto pulsando <Control><Alt><Fx> (siendo Fx cualquiera de las teclas F1 a F6), y volver al modo gráfico pulsando <Contro><Alt><F7>. Entendemos por ‘hacer login’ introducir el nombre de usuario y la password que se nos solicita.

También, desde el modo gráfico, puedes simplemente abrir una terminal gráfica (xterm, konsole, gnome-terminal), en este caso no se te pedirá login ya que ya estás identificado como usuario. Pero venga, que haces leyendo… ya estás tardando en probar todo lo que te he dicho…

Supongo que ya estás en la shell si es así a la izquierda del cursor seguramente habrá una frase corta seguida de un signo ‘$’, en mi caso tengo:

[redy@bbs redy]$ _

Ese es el prompt de usuario, si estás utilizando la cuenta del root en vez de un ‘$’ lo más probable es que tengas un ‘#’, es la forma que tiene la shell de avisarte que andes con cuidado con lo que haces pues puedes hacer de todo, (incluso cargarte el sistema). Normalmente todas las pruebas debemos hacerlas como usuario, a no ser que yo os indique lo contrario, así iremos más seguros.

Si estáis en Linux, lo más probable es que vuestra shell por defecto sea bash, que es a la que va destinada este curso, ¿como saberlo?, vamos a preguntárselo a la propia shell, así teclearemos nuestro primer comando del curso en la shell: escribid ‘echo $SHELL’ (sin las comillas) y darle al intro. Recordad que en Linux no es lo mismo escribir las cosas en mayúsculas que en minúsculas, hay que teclearlo exactamente como yo os lo pongo.

A partir de ahora y durante todo el curso cuando tengáis que teclear algo lo indicaré dentro de una etiqueta [code], así lo veréis con otro tipo de letra, y precedido del prompt ‘$’ si debéis hacerlo como usuario o ‘#’ si es necesario que hayáis hecho login como root. Ese primer caracter ‘$’ o ‘#’ no hay que teclearlo, es el que representa el prompt. Si hay más signos de ‘$’ o ‘#’ en la línea si deberéis teclearlos. Ni que decir tiene que siempre debéis acabar la línea con un intro (salvo que yo indique lo contrario).

$ echo $SHELL

Cuando quiera representar lo que os responde la shell al teclear un comando lo pondré también dentro de la etiqueta ‘code’ pero en otro color así será más fácil de entender que es lo que tecleáis y cual es la respuesta que se supone que debéis obtener. Por ejemplo con el comando anterior yo obtengo (y vosotros probablemente también): ‘/bin/bash’, o sea que según lo acordado escribiré.

$ echo $SHELL
/bin/bash

Si no es eso, (o algo muy similar pero que también termina en bash) lo que habéis obtenido es que vuestra shell por defecto no es bash. ¡Oh! estamos siguiendo un curso de bash y nuestra shell por defecto no es bash. Esto hay que arreglarlo enseguida….

No os preocupéis si de momento no entendéis bien lo que significa lo que tecleamos, para eso estamos aquí, para aprender este lenguaje, pero tiempo al tiempo…

En el apartado anterior os dije que se podía cambiar la shell, el curso está pensado para la shell bash, así que si esta no es vuestra shell por defecto ya la estáis cambiando, ahora os explico como.

Para saber que shells hay disponibles en vuestro sistema debéis usar el siguiente comando:

$ chsh -l
/bin/bash
/bin/sh
/bin/tcsh
/bin/csh
/bin/ash
/bin/bsh

El resultado en vuestro caso puede diferir en función de que shells estén instaladas, el ‘/bin/’ que precede a los nombre de la shell es el directorio donde se encuentra (puede variar en algunos casos, pero no es lo usual).

Para cambiar de shell usaremos el comando:

$ chsh
Changin shell for redy
password:

Aquí teclearemos nuestro pasword de usuario y luego nos preguntará

New shell [/bin/bash]:

A lo que le teclearemos una de las shells que obtuvimos con el comando anterior, como por ejemplo ‘/bin/sh’ (sin las comillas ¡eh!). Si no nos equivocamos nos dirá algo como…

Shell changed.

Indicando que la nueva shell está activada, y será la que se cargue en nuestra próxima sesión, así que si estamos en una consola de texto pura (<Ctrl><Alt><F1-F6>) teclearemos:

$ logout

y volveremos a entrar con el usuario, si ahora consultamos que shell estamos usando veremos que ha sido cambiada. (Recordad que si no habéis hecho login desde una consola de texto, sino que habéis abierto vuestra sesión desde un terminal gráfico no nos sirve este método, porque al abrir un terminal gráfico no se hace login realmente. Habría que cerrar nuestra sesión gráfica y volverla a abrir desde el login).

$ echo $SHELL
/bin/sh

Otra forma de hacer lo mismo es poniendo la shell que queremos como parte de la orden de esta forma, así ya no nos la preguntará luego, lo que si os preguntará siempre es la password.

$ chsh -s /bin/bash
Changing shell for redy.
Password:
Shell changed.

Haced todas las pruebas de cambio de shell que queráis, al final dejad como shell por defecto la bash, que es en la que se centra el curso…

Ordenes simples

Ya hemos visto como la shell espera que le introduzcamos una orden, indicándonoslo con el prompt, si comparamos el lenguaje bash con el castellano, podríamos decir que cada orden es como un frase. Cada orden consta de varios elementos (palabras) y tiene significado propio, puede ser interpretada y ejecutado por la shell. Como en nuestro idioma, toda frase debe tener normalmente un verbo, en bash los verbos son los comandos, que
generalmente van al principio de la orden. También, como en nuestro idioma el elemento que separa las palabras es el espacio en blanco, y no importa si ponemos uno o varios espacios entre palabras.

Hay ordenes que no tienen más que el comando, y hay otras que llevan argumentos adicionales.

  • Ejemplo de órdenes sin argumentos:

$ ls
$ jobs
$ groups

  • Ejemplo de órdenes con argumentos:

$ ls /bin
$ echo "Buenos días $USER"
$ tar -zxvf archivo_comprimido.tar.gz

En todos los ejemplos que hemos visto el comando es la primera palabra de la orden, esto es siempre así exceptuando algunos casos en los que el comando se omite, por ejemplo:

$ VAR=5

En esta orden VAR no es en realidad un comando, podríamos decir que esta orden sólo tiene argumentos.

$ DISPLAY=urano.home.net:0 gedit

En esta orden el comando es gedit, y no va en primer lugar, pero esto, claro está, son excepciones.

Todos los ejemplos vistos hasta ahora son ordenes simples, también existen ordenes compuestas, que veremos con más detalle más adelante. Para formar las ordenes compuestas se usan caracteres especiales como separadores, que funcionan del mismo modo que en nuestro idioma lo hacen las conjunciones. Las conjunciones sirven de nexo de unión entre frases simples para formar una frase compuesta y estos separadores de igual manera sirven de nexo de unión entre varias ordenes simples para formar una compuesta.

Por ejemplo la siguiente orden es compuesta porque consta de tres comandos que se ejecutarán uno tras otro y siempre y cuando el anterior haya finalizado con éxito.

$ ./configure && make && make install

(No pretendas entenderlo ahora, simplemente lo pongo como ejemplo de una orden compuesta).

Argumentos

Vale, entonces y por norma general la primera palabra de una orden simple es el comando. Luego separados por espacios van los argumentos. Y ya hemos dicho que para bash es lo mismo encontrar un espacio que varios consecutivos, así las dos órdenes siguientes hacen exactamente lo mismo.

$ echo Hola Pepe
$ echo Hola      Pepe

¿Hay diversos tipos de argumentos? Pues si, esto no es algo propio de bash. En Linux normalmente distinguimos los argumentos que denotan opciones, del resto, y dentro de las opciones hay opciones de un solo carácter y opciones de varios caracteres. Esto se explica mejor con ejemplos.

  • Comando simple sin argumentos

$ ls

  • Comando con opciones de un solo carácter (levan delante un ‘-‘)

$ ls -a -t -l

  • Si hay varias opciones de un solo carácter se pueden poner también todas juntas en forma abreviada, la orden anterior es igual que

$ ls -atl

  • Opciones de varios caracteres, las opciones de varios caracteres llevan casi siempre dos ‘-‘ en vez de uno, ya que de lo contrario se podría entender que son varias opciones de un solo carácter en forma abreviada.

$ ls --color

  • Otros argumentos:

$ ls /usr/bin

  • O todo mezclado:

$ ls -atl --color /usr/bin

Entre las utilidades GNU suele cumplirse la regla de que las opciones de un solo caracter llevan un simple signo menos y las de varios caracteres llevan un doble signo menos. Pero no hay regla sin excepción, y en linux podemos encontrar un conjunto tan heterogéneo de utilidades que no todos los programadores la respetan y así encontraremos por ejemplo casos como el comando:

$ ps axu

en el que la a, la x y la u son ociones de un solo caracter pero que no llevan el signo menos delante. Igual que ocurre en el siguiente comando con la j, la x, la v, y la f.

$ tar jxvf fichero.tar.gz

O incluso comandos con opciones largas de varios caracteres que no llevan el doble signo menos. Por ejemplo en los siguientes comandos lo suyo es que las opciones ‘resize’ o ‘scanbus’ fuesen precedidas de doble signo menos pero no es así.

$ convert foto.jpg -resize 800x600 foto_800x600.jpg
$ cdrecord -scanbus

Ante la duda solo queda recurrir a la documentación del comando.

Introduciendo órdenes, y atajos de teclado

Hasta ahora vimos que hay un prompt, ante el que tecleamos órdenes sencillas, y cuando damos al intro se ejecutan. A partir de ahora habrá que ir trabajando con el bash, así que este es el momento de explicar más a fondo todas las posibilidades de bash a la hora de introducir órdenes, ello nos facilitará mucho la tarea…

En un Linux bien configurado, y siempre que estemos en un terminal Linux, mientras le introducimos una orden a bash, podemos movernos por ella a la izquierda o a la derecha con las teclas del cursor, o borrar con la tecla de retroceso (backspace) o con la tecla de suprimir. Esto que parece tan normal, no siempre funciona ya que podemos encontrarnos en una consola remota (accediendo por telnet o por ssh desde otra máquina) que no permite o que no tiene configuradas esas teclas de control como lo espera Linux. Eso no será ningún problema si conocemos los siguientes atajos de teclado. Procuraré acompañar las secuencias de teclas de ciertas reglas nemotécnicas, la mayoría asociadas a palabras inglesas, para que sean más fáciles de recordar. Estas reglas las pongo entre paréntesis (Generalmente si una tecla combinada con <Control> hace algo con una letra, esa misma tecla combinada con <Alt> hace lo mismo pero con una palabra.):

Aquí hay que hacer notar que en una consola de texto pura no tendremos problemas, pero si estamos en el entorno gráfico es posible que en nuestro desktop alguna de esas combinaciones de teclas esté asignada como ‘hotkey’, o que el emulador de terminal gráfico la asigne a algun menú. Por ejemplo en el gnome-terminal <Alt>U despliega la ayuda, con lo cual el bash jamás recibirá esa combinación de teclas orque es atrapada antes, y no tendrá el efecto esperado.

  • <Control>A Ir al principio de línea (La A está al principio del alfabeto).
  • <Control>E Ir la final de línea (E de End=Final).
  • <Control>F Hace lo mismo que la flecha hacia la derecha, avanza un carácter
  • <Alt>F Avanza una palabra (Recordad F de forward=adelante)
  • <Control>B Hace lo mismo que la flecha hacia la izquierda, retrocede.
  • <Alt>B Retrocede una palabra (B de Back=atrás)
  • <Control>L Borra la pantalla dejando solo la línea que estamos escribiendo (L de limpiar)
  • <Control>D Borra el carácter bajo el cursor como la tecla <Supr> (Delete)
  • <Alt>D Borra desde el cursor hasta el final de la palabra.
  • <Control>H Borra el caracter anterior al cursor.
  • <Control>W Borra desde el cursor hasta principio de la palabra. (Ya sé que atendiendo a la lógica debiera ser <Alt>H pero no es así :-( supongo que la W es por ‘word’: palabra ).
  • <Control>K Borrar desde el cursor hasta el final de la línea (trunKar).
  • <Control>U Borrar desde el cursor hasta el principio de la línea.
  • <Control>Y Generalmente cuando borramos una o varias palabras o un bloque, podemos luego mover el cursor a otra posición si es necesario y volver a pegar el bloque borrado en la nueva posición con esta combinación de teclas.
  • <Control>C Limpia la orden que estamos tecleando como si no hubiésemos tecleado nada (Clear=limpiar)

Estas quizá sean menos útiles, pero ahí van…

  • <Alt>U Convierte a mayúsculas desde el cursor hasta el final de la palabra (Upper case=Mayúsculas).
  • <Alt>L Convierte igual pero a minúsculas (Lower case=Minúsculas).
  • <Alt>C Pone la letra en la que está el cursor en mayúsculas y el resto hasta el final de la palabra en minúsculas (Poner en letra Capital).
  • <Control>T Intercambia el caracter sobre el que está el cursor con el inmediatamente anterior, por ejemplo si hemos escrito ‘fihcero’ y ponemos el cursor sobre la ‘c’ al pulsar esta combinación de tecla se intercambia la c con la h quedando ‘fichero’ (T de transponer)
  • <Alt>T Lo mismo con palabras si escribimos ‘Rodriguez Redy’ y con el cursor en cualquier posición de la segunda palabra, pulsamos esta combinación, se intercambiarían las dos palabras quedando ‘Redy Rodriguez’

Historial de ordenes: Esto si que es muy interesante, todas las órdenes que vamos escribiendo, quedan en un historial, podemos recuperar de nuevo las últimas ordenes tecleadas con la flecha hacia arriba. Bueno en realidad podemos navegar por el historial con las flechas arriba y abajo. Y como decía arriba, si las flechas no funciona podemos usar las siguientes teclas para navegar por la historia de ordenes:

  • <Control>P Recupera la orden anterior en la historia (P de previo).
  • <Control>N Recupera la orden siguiente (N de Next=Siguiente).

(Se pueden usar también las flechas del cursor. Flecha arriba va a la orden anterior y flecha abajo a la siguiente.)

  • <Alt> < Va a la primera orden de la historia.
  • <Alt> > Va a la última orden de la historia. Esto en algunos Linux esats dos últimas combinaciones pueden no funcionar con la configuración del teclado en castellano.
  • <Control>R Busca una palabra hacia atrás en la historia.

Pulsamos <Control>R y el prompt cambiará por algo similar a

reverse-i-search :

empezamos a escribir una palabra. La última orden que hayamos tecleado que contenga esa palabra se mostrará y desde el momento que pulsemos cualquier tecla de edición cesa la búsqueda y podremos modificarla, o simplemete introducirla tal como está pulsando Intro.

Autocompletar: Más interesante todavía que la historia es la posibilidad de completar de forma inteligente lo que vamos escribiendo, para autocompletar se usa la tecla del tabulador <tab>.

¿Como funciona esto? pues si estamos escribiendo la primera palabra de una orden, la shell espera, como es lógico, un comando; así que si tecleo por ejemplo ‘ec’ y pulso el tabulador, bash busca todos los posibles comandos que empiezan por ‘ec’ como solo hay uno, que es echo pues lo completa. Si hubiese varios comandos que empezaran por ‘ec’ primero daría un aviso sonoro indicando que no es capaz de saber que es lo que quiero teclear, si insisto con el tab me mostrará todas las posibilidades, para que pueda teclear alguna letra más y volver a pulsar el tab si quiero. Si ya tecleé el comando y estoy el la segunda o sucesivas palabras, intenta completar con los nombres de archivo, o con lo que más sentido tenga por ejemplo si intento autocompletar una palabra que empieza por $ lo hará con los nombres de las variables definidas, etc… (no te preocupes si no sabes lo que es una variable, ya lo veremos más adelante). En algunos terminales, dependiendo de como estén configurados, puede que el aviso sonoro no se escuche o que sea sustituido por uno visual.

Hay un paquete adicional, que no viene con la instalación por defecto de bash llamado bash completion, que mejora el comportamiento del autocompletado de bash hasta el punto de que si usamos tabulador después de determinados comando consulta la ayuda de se comando para ver que argumentos admite y nos los muestra y muchas mas facilidades. Si está disponible para tu distribución, no dejes de instalarlo, te hará la vida en la consola un poco más fácil.

Bueno una cosa más en cuanto a la introducción de órdenes: Decía al principio que el prompt normalmente puede tener un ‘$’ si estamos como usuarios o un ‘#’ si estamos como root, hay que decir que en algunos casos se pueden mostrar otros prompts. Cuando bash, pese ha que le hemos tecleado un intro entiende que la orden no está todavía terminada, muestra el prompt ‘>’ para indicarnos que debemos seguir. Por ejemplo si abrimos unas comillas y nos olvidamos de cerrarlas, al pulsar el intro bash sabe que falta algo, y nos lo pregunta con ese prompt. Luego hay un tercer y un cuarto prompt pero ya los veremos más adelante, no quiero adelantar acontecimientos.