Imprimir

Manual de Bash: lo más básico

Al shell Bash, el intérprete de comandos estándar en Linux, le podemos pasar comandos desde una terminal o desde un script, que es un archivo de texto que contiene un pequeño programa.

'Hola mundo' en Bash

El script más sencillo es Hola mundo. Veamos cómo crearlo:

  • crearemos el script con un editor de texto. En Linux disponemos de numerosos editores avanzados orientados a programación, con resaltado de sintaxis, como Gedit, Kwrite, Kate, Scite, etc.
  • llamaremos a nuestro script hello.sh. A los scripts del shell se les suele poner la extensión .sh para identificarlos más fácilmente.
  • en un script podemos incluir cualquier comando que se pueda ejecutar en el intérprete de comandos. En nuestro caso, el contenido de hello.sh será el siguiente:
    #!/bin/bash
    echo "Hola, mundo."
  • la primera línea indica la aplicación que interpretará los comandos del script, en este caso Bash, cuyo ejecutable es /bin/bash.
  • le daremos al script permisos de ejecución con el comando chmod:
    $ chmod a+x hello.sh
  • para ejecutar el script añadiremos al nombre del script la ruta del directorio actual, "./", ya que el directorio donde se encuentra (nuestra carpeta personal) no está en el PATH:
    $ ./hello.sh

    También podemos ejecutar el script llamando a bash:

    $ bash hello.sh

    En ambos casos obtendremos por la salida estándar (la pantalla) lo siguiente:

    Hola mundo Bash

Comentarios

Las líneas que comienzan por el carácter "#" (excepto la primera), se consideran comentarios y son ignoradas por el intérprete de comandos.

Argumentos de los scripts

A un script se le pueden pasar argumentos.

  • Dentro del script estos argumentos se almacenan en las variables de nombre $0, $1, $2, ..., $9.
  • La variable $0 almacena el nombre del script, mientras que $1, $2, ..., $9 almacenan los argumentos propiamente dichos.
  • Sólo hay nombre específico para los nueve primeros argumentos (más el propio nombre del comando), pero el comando shift hace posible utilizar y distinguir parámetros que están más a la derecha del noveno lugar en la llamada al script. Cuando se ejecuta el comando shift dentro del script, $2 se convierte en $1, $3 en $2, etc, y lo que hubiera sido $10 en $9, es decir, que se recorta la lista de argumentos una posición quitando el primero de ellos, con lo cual ya se puede referenciar. El comando shift deja inalterado $0 y puede utilizarse tantas veces como se desee (ver ejemplo de shift en Programar en Bash: funciones).
  • El número de argumentos que se le pasa al script está contenido en la variable $#.
  • El conjunto de todos los argumentos está almacenado en la variable $*.

Veamos por ejemplo el siguiente script, llamado args.sh:

#!/bin/bash
echo "\$0 contiene $0"
echo "\$1 contiene $1"
echo "\$2 contiene $2"
echo "En total hay $# parametros"

Ejecutamos este script sin pasarle argumentos:

$ ./args.sh
$0 contiene ./args.sh
$1 contiene
$2 contiene
En total hay 0 parametros

Ahora ejecutamos el script pasándole dos argumentos:

$ ./args.sh buenos dias
$0 contiene ./args.sh
$1 contiene buenos
$2 contiene dias
En total hay 2 parametros

Veamos un ejemplo de script al que se le pasa sólo un parámetro. El comando de borrar de Linux rm no pide confirmar la operación de borrado si no se le pone la opción "-i". Esto es peligroso porque uno fácilmente puede olvidarse de teclear dicha opción y borrar lo que no quería borrar. Vamos a crear un script llamado del.sh que incluya dicha opción. Dicho archivo podría ser:

#!/bin/bash
echo "Quiere borrar el archivo $1?"
rm -i $1

Después de darle a este archivo el correspondiente permiso de ejecución con el comando chmod, podríamos borrar con confirmación el archivo file1 tecleando:

$ del.sh file1

Dentro del archivo de comandos, $0 valdría del y $1 valdría file.

Veamos ahora un script al que se le pasan dos parámetros. El programa cambio.sh intercambia el nombre de dos archivos:

#!/bin/bash
mv $1 archivotemp
mv $2 $1
mv archivotemp $2

Para ejecutar este programa haremos:

$ cambio.sh file1 file2

En este ejemplo $0 es cambio.sh, $1 es file1 y $2 es file2.

Veamos un ejemplo con mútiples argumentos. Si el programa del.sh que hemos hecho previamente lo hubiéramos utilizado en la forma:

$ del.sh *.f

teóricamente debería borrar, con confirmación, todos los archivos Fortran del directorio (*.f). En la práctica no es así, porque $1 sólo almacena el primer archivo Fortran y es el único que borra. Para borrar todos el script del.sh podría ser:

#!/bin/bash
echo "Hay # programas para borrar \n"
rm -i *

Salir del script

El comando para terminar el script es exit. Este comando no es útil al final del script, pero sí para terminar el programa en algún punto intermedio, por ejemplo "si se da tal condición, entonces terminar". Además, el comando exit permite establecer el valor de retorno, el valor devuelto por el script.

Valor de retorno

Cuando se ejecuta un programa o comando devuelve un valor numérico, que será:

  • cero (0) si el programa finalizó con éxito.
  • distinto de cero si el programa no finalizó con éxito. Cada uno de los valores distintos de cero va asociado a una causa distinta: sabiendo este valor podemos saber por qué razón falló el programa.

El valor de retorno no se imprime por la pantalla, es decir, cuando un programa termina no saca por pantalla un cero u otro número, sino que el valor de retorno del último programa ejecutado queda almacenado en la variable especial $?.

Veamos un ejemplo:

#!/bin/bash
echo "Listando archivo existente..."
ls archivo_existente
echo "El valor de retorno fue: $?"
echo " "
echo "Listando archivo inexistente..."
ls archivo_inexistente
echo "El valor de retorno fue: $?"

Primero listamos un archivo existente: lo lista con éxito y por tanto el valor de retorno es 0. A continuación, listamos un archivo inexistente: como eso no es posible, el comando no termina con éxito y el valor de retorno es distinto de cero (en este caso 1).

Utilizaremos el valor de retorno para saber si los comandos del script han tenido éxito o no, pudiendo emplear esta información en sentencias condicionales.

El comando para terminar el script, exit, permite establecer el valor de retorno (el valor devuelto por el script), para así obtener información acerca de si el script ha tenido éxito o no y porqué. Por ejemplo:

#!/bin/bash
if [ expresion1 ]; then
    Bloque 1
    exit 0
else
    Bloque 2
    exit 1
fi

Variables en los scripts

Para que una variable definida dentro de una función, bucle o estructura sea de ámbito local (sólo existe en esa estructura) debemos declararla como local con el comando local:

local j=8

Las variables que no se definan expresamente como locales, se definan donde se definan, serán de ámbito global, y por tanto, accesibles en cualquier lugar del programa.

Introducir datos por el teclado

Para introducir datos por el teclado usaremos el comando read. Para ver cómo funciona, veamos el siguiente script:

#!/bin/bash
frase="Introduzca lo que usted quiera:"
echo $frase
read entrada_del_usuario
echo " "
echo "Usted introdujo: $entrada_del_usuario"

Cuando se ejecute el script, al llegar al comando read esperará a que el usuario escriba algo y presione la tecla <INTRO>. A continuación, almacenará la entrada del usuario en la variable $entrada_del_usuario.

Evaluar expresiones

El comando que permite evaluar expresiones es test: el valor de retorno será cero (0) si la expresión es VERDADERO (TRUE), y uno (1) si la expresión es FALSO (FALSE). La sintaxis es:

test <expresion>

Veamos un ejemplo:

#!/bin/bash
a=7
b=8
test $a -eq $a
echo $?
test $a -eq $b
echo $?

Si ejecutamos el script obtendremos:

0
1

El primer comando quiere decir: ¿es $a igual a $a? Vemos que el valor de retorno es cero (0), lo cual indica que la expresión es VERDADERO: efectivamente $a es igual a $a. El segundo comando comprueba si $a igual a $b: el valor de retorno de test es uno (1), ya que la expresión es FALSO: $a no es igual a $b.

Existe otra sintaxis para evaluar una expresión, algo más clara:

[ expresion ]

Veamos un ejemplo:

#!/bin/bash
a=7
b=8
[ $a -eq $b ]
echo $?

Si ejecutamos el script obtendremos:

1

Algunos de los operadores que admite test son:

  • para comparar enteros:
    [ integer1 -eq integer2 ]
    • -eq igual (equal).
    • -ne distinto (not equal).
    • -ge mayor o igual (greater than or equal).
    • -gt mayor (greater than).
    • -le menor o igual (less than or equal).
    • -lt menor (less than).
  • para comparar o aplicar a cadenas:
    [ string1 = string2 ], [ -z string1 ]
    • = igual.
    • != distinto.
    • -z la longitud de la cadena es cero.
  • para comparar o aplicar a archivos:
    [ file1 -nt file2] , [ -e file1 ]
    • -nt fecha de modificación más reciente (newer than).
    • -ot fecha de modificación más antigua (old than).
    • -e el archivo existe.
    • -s el archivo existe y tiene un tamaño mayor que cero.
    • -d el archivo existe y es un directorio.
    • -h el archivo existe y es un enlace simbólico.
    • -x el archivo existe y es ejecutable.

3 Comentarios en “Manual de Bash: lo más básico”

  • CUTI dice:

    QUIERO RESOLUCION DE 2 SCRIPTS IMPORTANTES

    1. Crear un script llamado uno.sh que busque dentro de un fichero las líneas que contienen una palabra, tanto el nombre de fichero, como la palabra que se quiere buscar se pasarán por la línea de comandos. Se debe comprobar:

    • Que se pasen exactamente dos parámetros.
    • Que el fichero debe existir.

    Ejemplo:

    Miserver @ usuario$ uno.sh /home/usuario/jfsfj.txt redes

    2. Crear un script llamado dos.sh que pida por pantalla dos números y muestre por pantalla la secuencia de números que hay entre el menor y el mayor, al lado de cada número debe aparecer su cuadrado.

    Ejemplo 1
    Introduce el primer número: 5
    Introduce el segundo número: 1
    1 1
    2 4
    3 9
    4 16
    5 25
    Ejemplo 2
    Introduce el primer número: 2
    Introduce el segundo número: 6
    2 4
    3 9
    4 16
    5 25
    6 36

  • Iván dice:

    en la comparación con enteros tienes
    “-t menor (less than)”
    y lo correcto es
    “-lt menor (less than)”

    puede ser importante, a mi me ha llevado un rato darme cuenta, en todo caso gracias por contribuir publicando estas cosas.

    Un saludo,
    Iván.

  • carlos.piano dice:

    A CUTI:

    1.- uno.sh
    —————————————————————————————–
    #!/bin/bash
    if [ $# -ne 2 ]; then
    echo “No se han introducido dos parámetros”; exit 1
    fi
    # Esto comprueba el nº de parámetros
    if [ -e $1 ];then
    echo “”
    else
    echo “El fichero no existe”; exit 2
    fi
    # Esto comprueba la existencia del fichero
    grep –file=”$1″ $2
    —————————————————————————————–
    El fichero dos.sh depende de la versión de BASH que tengas.

Deja un comentario