Tutorial de Programación Bash Shell Script en Linux

¿Qué es el lenguaje Bash?

Bash es un lenguaje de programación que se utiliza principalmente en sistemas operativos Linux y Unix. Se trata de un lenguaje de scripting, lo que significa que bash se utiliza generalmente para automatizar tareas repetitivas o para simplificar tareas complejas. Por ejemplo, podría usar bash para escribir un script que realice copias de seguridad de todos los archivos en su sistema o para crear un script que instale y configure automáticamente un nuevo software.

Bash también se utiliza a menudo como un intérprete de línea de comandos, lo que significa que bash puede ejecutar directamente los comandos que le digas. Esto es útil si necesitas ejecutar un comando repetidamente o si necesitas ejecutar un comando en varios sistemas. Por ejemplo, podría usar bash para escribir un script que busque y elimine todos los archivos duplicados en su sistema.

¿Por qué bash es popular?

Bash es popular porque es fácil de aprender y usar. Bash también es muy versátil, lo que significa que bash puede hacer muchas cosas. Por ejemplo, bash puede leer y escribir archivos, ejecutar otros programas, realizar cálculos matemáticos y mucho más. Esto hace que bash sea ideal para automatizar tareas repetitivas o para simplificar tareas complejas.

¿Qué es un script?

La programación de scripts en Linux es fundamental para cualquier administrador del sistema operativo.

Un script es, básicamente, es un lenguaje de programación del propio sistema operativo para realizar y automatizar todas aquellas tareas de administración que necesitemos como, por ejemplo, iniciar y detener servidores o para administrar archivos de configuración, entre otras muchas.

Por lo general, un script de shell está escrito en uno de los siguientes lenguajes: Bash, Tcsh o Ksh. Puede tomar cualquier nombre, pero debe terminar con «.sh».

En el mundo profesional, un administrador de sistemas podría administrar más de 500 servidores el sólo, por lo que la automatización mediante scripts es muy importante para agilizar el proceso.

¿Es fácil programar un script en Linux?

Personalmente, suelo programar con lenguaje Bash  (Bourne Shell). Hace unos años utilizaba más Korn Shell o ksh, cuando administraba los servidores HP-UX. Ahora me dedico más a RedHat y bash es el que viene por defecto (aunque se pueden utilizar otras shells).

Si ya sabéis programar en otros lenguajes de programación, no tendréis mucho problema para aprender Bash. Básicamente, se basa en variables, bucles de repeticiones (while y for), condiciones (if then)… pero orientado a la gestión del sistema operativo.

Turorial para la creación de scripts en Linux con bash
Operaciones aritméticas con expr en bash

Ventajas de la programación en Bash

Hay varias ventajas de scripts bash. Estas ventajas incluyen legibilidad, flexibilidad y potencia. La programación bash a menudo es utilizada por científicos informáticos y aficionados por igual. Si tienes curiosidad por el idioma, aquí hay tres cosas que debes saber: ¡es gratis! Además, Bash es de código abierto, lo que significa que puede traducirlo a otros idiomas.

Como intérprete de comandos, Bash se puede usar para automatizar muchas tareas.

Los administradores del sistema (Linux/UNIX) pueden usar BASH para solucionar problemas de sistemas de mal funcionamiento, distribuir actualizaciones de software, monitorizar los sistemas de ejecución y una larga lista de tareas relacionadas con la administración del sistema operativo.

Los desarrolladores de software también usan BASH para automatizar muchas tareas de desarrollo. Desde la automatización de las pruebas hasta la optimización del rendimiento de la red, Bash puede hacer que su trabajo sea mucho más fácil.

Las variables y las matrices se pueden usar en la programación BASH. Sin embargo, no es necesario declararlos como matrices. Por ejemplo, si deseamos imprimir el estado de salida actual de un proceso anterior, usaremos el símbolo $ (que es una variable de Bash). También podemos usar variables personalizadas, condiciones y bucles for o while y ejecutar comandos del sistema operativo.

Utilizaremos el parámetro -x (sh -x script) para ejecutar el script en modo de depuración para tratar de resolver errores dentro del script.

A continuación, repasaremos todo esta información y ejecutaremos varios scripts en bash a modo de aprendizaje. Ya verás como es muy sencillo.

Uso de variables

Como podemos ver en el siguiente ejemplo, si ejecutamos el script con un punto, un espacio y el nombre del script, imprimiremos por pantalla el valor de la variable $NOMBRE. A esto se le llaman «variables de entorno».

#!/bin/sh

NOMBRE=David
APELLIDO=$1
echo $NOMBRE $APELLIDO

COMANDO=$(grep David nombres.txt)
echo En el fichero nombres.txt se encuenta el nombre $COMANDO
[root@localhost scripts]#

[root@localhost scripts]# ./variables.sh Martinez
David Martinez
En el fichero nombres.txt se encuenta el nombre David
[root@localhost scripts]# 

Las variables de entorno se utilizan mucho en los inicios de sesión de los usuarios ($HOME/.profile).

En el ejemplo anterior también hemos visto que el nombre de una variable se asigna como «Nombre_Variable=valor» e imprimiremos su valor poniendo el símbolo del dólar delante ($Nombre_Variable).

Variables especiales

#  Guarda el número de parámetros asociados a la ejecución del script.
*  Guarda la cadena de caracteres de los argumentos.
?  Guarda el código de error devuelto por la última orden del script (0 = sin errores).
@  Guarda la cadena de parámetros entera pero como una lista de cadenas y no como una sola.
$0  En realidad no es una variable reservada, sino que representa al primer campo de la línea de argumentos, que es el nombre del script.

Esto significa que en un script podemos imprimir en pantalla la variable «@», por ejemplo, con «echo $@».

Ejemplo:

# cat parametros.sh #!/bin/bash 
PARAMETRO1=$1 
PARAMETRO2=$2 
PARAMETRO3=$3 
ARRAY_PARAMETROS=$@ HORA=$(date) 
echo El valor del parametro1 es: $PARAMETRO1 echo El valor del parametro2 es: $PARAMETRO2 echo El valor del parametro3 es: $PARAMETRO3 echo El código de error devuelto por el último comando del script ha sido: $? 
echo El número de parámetros asociados a este script son: $# echo Los parámetros que se han pasado son: $* 
echo Asignamos un comando a una variable, que nos da la hora actual: 
$HORA 
# ./parametros.sh param1 param2 param3 
El valor del parametro1 es: param1 
El valor del parametro2 es: param2 
El valor del parametro3 es: param3 
El código de error devuelto por el último comando del script ha sido: 0 
El número de parámetros asociados a este script son: 3 
Los parámetros que se han pasado son: param1 param2 param3 
Asignamos un comando a una variable, que nos da la hora actual: lun dic 1 16:22:54 CET 2008

Leer el valor de una variable

Un ejemplo sencillo:

[root@localhost scripts]# cat escribe_nombre.sh 
#!/bin/sh

echo Escribe tu nombre: 
read Nombre 
echo Escribe tu apellido: 
read Apellido1  
echo Tu nombre completo es: $Nombre $Apellido1 
[root@localhost scripts]#

[root@localhost scripts]# ./escribe_nombre.sh 
Escribe tu nombre:
David
Escribe tu apellido:
Martinez
Tu nombre completo es: David Martinez
[root@localhost scripts]# 

Decalarar una variable booleana en bash

En bash también podemos declarar variables booleanas como en cualquier otro lenguaje de programación, para utilizarlas en condicionales. En realidad, hacemos una pequeña trampa utilizando strings. Veamos un ejemplo:


#Asignamos el valor true a la variable (en realidad es un string)
varbool=true
 
# Test the variable value
if [ "$varbool" = 'true' ]; then
   echo "Es verdad"
else
   echo "Es falso"
fi

Concatenar strings con Bash

Con bash también podemos concatenar (o unir) dos cadenas de texto (strings) almacenadas en variables diferentes. Veamos un ejemplo:

[root@server1]# cat concatenate.sh
#!/bin/bash

var1="Hola"
var2="Mundo"
var3="$var1 $var2"

echo "$var3"
[root@server1]#

[root@server1]# ./concatenate.sh
Hola Mundo
[root@server1]# 

Operaciones aritméticas

Con el comando expr podremos sumar, restar multiplicar o dividir.

Operadores aritméticos
+Suma
Resta
*Multiplicación
Nota: este símbolo también corresponde con una variables especial para la shell, por lo que si lo queremos usar como multiplicación, lo tendremos que escribir como “\*”.
/División
%Resto de la división
Operadores relacionales
=Igual
!=Diferente
>Mayor que
>=Mayor o igual que
<Menor que
<=Menor o igual que
Operadores lógicos
| (pipe)Operación “O”
&Operación y “AND”

Ejemplo:

[root@localhost scripts]# cat aritmeticas.sh 
#!/bin/sh

SUMA=`expr 15 + 30`
echo $SUMA

RESTA=`expr 30 -  20`
echo $RESTA

MULTIPLICA=`expr 2 \* 5`
echo $MULTIPLICA

DIVIDE=`expr 10 / 2`
echo $DIVIDE

RESTO=`expr 13 / 3`
echo $RESTO

[root@localhost scripts]# ./aritmeticas.sh 
45
10
10
5
4
[root@localhost scripts]# 

Si no queremos utilizar el comando «expr» también podemos utilizar bash script de la siguiente manera:

# echo $((4 + 3))
7
#

¿Cómo escribir un número aleatorio en BASH?

Para escribir un número aleatorio en Bash, sencillamente, utilizaremos la variable de entorno RANDOM:

# echo $RANDOM
31610
# echo $RANDOM
6999
# echo $RANDOM
7300
# echo $RANDOM
12597
# echo $RANDOM
5497
# 

Evaluar expresiones con el comando test

  • Parámetros relacionados con los archivos:

-f → Devuelve 0 si el archivo existe y no es ni un directorio ni un dispositivo.

-s → Devuelve 0 si el archivo existe y tiene un tamaño mayor que 0.

-r → Devuelve 0 si el archivo existe y tiene permiso de lectura.

-w → Devuelve 0 si el archivo existe y tiene permiso de escritura.

-d → Devuelve 0 si la búsqueda pertenece a un directorio.

  • Parámetros relacionados con las cadenas de texto:

-z → Devuelve 0 si el número de caracteres de una cadena es igual 0.

-n → Igual que el parámetro anterior con la diferencia de que comprueba que el tamaño de la cadena sea mayor que 0.

  • Parámetros relacionados con números:

-lt → Menor que

-le → Menor o igual que

-gt → Mayor que

-ge → Mayor o igual que

-eq → Igual a

-ne → Diferente a

Ejemplo:

[root@localhost scripts]# cat testsc.sh 
#!/bin/bash 

echo -n "Vamos a comprobar que existe el archivo testsc.sh: " 
test -f "testsc.sh"
echo $? 

CADENA="Soy una cadena de texto" 
echo -n "Vamos a comprobar si una cadena de texto está vacía: " 
test -z "$CADENA" 
echo $? 

NUM1=10 
NUM2=20
echo -n "Vamos a comprobar si NUM1 es mayor que NUM2: " 
test $NUM1 -gt $NUM2 
echo $?
[root@localhost scripts]# 

[root@localhost scripts]# ./testsc.sh 
Vamos a comprobar que existe el archivo testsc.sh: 0
Vamos a comprobar si una cadena de texto está vacía: 1
Vamos a comprobar si NUM1 es mayor que NUM2: 1
[root@localhost scripts]# 

Bucle if then

Se utiliza para ejecutar una función si se cumple una condición.

Ejemplo:

[root@localhost scripts]# cat ifsc.sh
#!/bin/bash 
# Comprobamos si está escuchando el puerto 80, típico de un Webserver

WS=`netstat -an |grep " 80 " |grep LISTEN` 

# Si la cadena de texto está vacía 
if [[ -z $WS ]] 
then 
 echo No tenemos ningún servicio arrancado y escuchando por el puerto 80. 

 # De lo contrario else echo Tenemos un Webserver arrancado 
else
   echo El Webserver si esta arrancado por el puerto 80

fi 
[root@localhost scripts]# 

[root@localhost scripts]# ./ifsc.sh 
No tenemos ningún servicio arrancado y escuchando por el puerto 80.
[root@localhost scripts]# 

Bucle case esac

Compara el valor de una variable con cada uno de sus condicionantes.

Ejemplo:

# cat casesc.sh 
#!/bin/bash 
echo Escribe un número del 1 al 3: 
read NUM 
case $NUM in 
1) echo Has escrito el número 1;; 
2) echo Has escrito el número 2;; 
3) echo has escrito el número 3;; 
 *) echo El número o la palabra escrita no coincide con el rango solicitado;; 
esac 
#
# ./casesc.sh Escribe un número del 1 al 3: 
2 
Has escrito el número 2 
[usuario1@noname00 scripts]$ ./casesc.sh Escribe un número del 1 al 3: 
5 
El número o la palabra escrita no coincide con el rango solicitado
#

Bucle while

Se ejecutan una serie de instrucciones mientras se cumple una condición.

Ejemplo:

[root@localhost scripts]# cat whilesc.sh 
#!/bin/sh

while read line 
do
 echo $line 
done < nombres.txt 
[root@localhost scripts]# 

[root@localhost scripts]# ./whilesc.sh 
David
Javi
Laura
Jordi
[root@localhost scripts]# 

Crear un bucle infinito en bash con while

Si por alguna razón necesitamos crear un bucle infinito, con while lo podemos hacer sin problemas. Por ejemplo:

while true
do

Acciones de nuestro script

done

Bucle for

Se ejecutan una serie de instrucciones hasta que finalice el recorrido de una lista.

[root@localhost scripts]# cat forsc.sh 
#!/bin/bash 
for i in `seq 1 10`; do 

   echo el valor de la variable 'i' es: $i 

done
[root@localhost scripts]# 

[root@localhost scripts]# ./forsc.sh 
el valor de la variable i es: 1
el valor de la variable i es: 2
el valor de la variable i es: 3
el valor de la variable i es: 4
el valor de la variable i es: 5
el valor de la variable i es: 6
el valor de la variable i es: 7
el valor de la variable i es: 8
el valor de la variable i es: 9
el valor de la variable i es: 10
[root@localhost scripts]# 

Salir de un bucle while o for

Para salir de un bucle while o for antes de que finalice, utilizaremos las siguientes instrucciones dentro del bucle:

  • break: Salimos completamente del bucle y continuamos con la ejecución del script.
  • continue: Salimos de la ejecución actual del bucle pero continuamos con la siguiente repetición.
  • exit n: Detiene la ejecución del script y se asigna a n el código de error.

Uso de arrays o conjuntos

Un array es un conjunto de variables agrupadas en una sola pero que podemos apuntar a cada uno de sus valores de manera individual.

[root@localhost scripts]# cat array.sh 
#!/bin/bash 
miarray=(rojo verde azul) 

echo Valor de la primera posición del array: ${miarray[0]} 
echo Valor de la segunda posición del array: ${miarray[1]} 
echo Valor de la tercera posición del array: ${miarray[2]} 
[root@localhost scripts]#

[root@localhost scripts]# ./array.sh 
Valor de la primera posición del array: rojo
Valor de la segunda posición del array: verde
Valor de la tercera posición del array: azul
[root@localhost scripts]#

Funciones creadas por nosotros mismos

Con el objetivo de ahorrar código, podemos escribir una función y llamar al código de esa función cada vez que lo necesitemos.

Ejemplo:

Fichero con la definición de funciones

# cat linux_system.lib 
#!/bin/ksh

linux_system_halt ()
{

echo Stopping the system
 cd /
 /sbin/shutdown -h 0

}

linux_system_reboot ()
{

echo Rebooting the system
 cd /
 /sbin/shutdown -r 0

}

cpu_usage ()
{

echo "%CPU PID USER COMMAND"
 ps -eo pcpu,pid,user,args | sort -rnk1 | head -10

}

memory_usage ()
{

echo Los 20 procesos que mas memoria estan consumiendo:
 echo
 ps -e -o vsz=Kbytes -o ruser -o pid,args=Command-Line | sort -rnk1 | head -20

}

get_num_processors ()
{

NUMPROCESSORS=`cat /proc/cpuinfo |grep MHz |wc -l`
 echo "Este servidor tiene $NUMPROCESSORS CPUs".

}

get_memory_assigned ()
{

/usr/bin/free |head -2

}
#

Script que hace llamadas a las funciones definidas previamente

# cat linux_system.sh
#!/bin/ksh

# Library load
LPATH=/usr/local/bin/sh_expl/LIB
. $LPATH/linux_system.lib

#########################

ACTION=$1

case $ACTION in
reboot_linux) linux_system_reboot ;;
halt_linux) linux_system_halt ;;
cpu_usage) cpu_usage ;;
memory_usage) memory_usage;;
num_processors) get_num_processors;;
get_memory_assigned) get_memory_assigned;;
*) Option not implemented ;;
esac
#

Lo que he explicado en este artículo es muy básico pero ya sirve para comenzar a crear nuestros primeros scripts.

Te puede interesar

Crear, modificar o eliminar usuarios y grupos en Linux

COMPÁRTEME

Deja un comentario