Programación Bash#

Logo Programación Bash

Última edición el día 2023-02-06 a las 12:26.

Esta es la documentación que he recopilado para programar en bash.

Elementos básicos del lenguaje#

En linux existen varios tipos de Shells:

  • Bourne shell (sh)

  • C shell (csh)

  • Korn shell (ksh)

  • TC Shell (tcsh)

  • Bourne Again Shell (bash)

La mas popular es bash y es la que usaremos para estos comandos.

Crear un script#

  • Creamos un archivo nuevo nano prueba-bash.sh y añadimos lo siguiente:

1#!/bin/bash
2
3echo "Prueba de bash ejecutada"
  • Añadimos permisos de ejecución al archivo: chmod +x prueba-bash.sh.

  • Ejecutamos el script: ./prueba-bash.sh

Atención

La primera línea es obligatoria e indica el tipo de shell va a interpretar el script.

Nota

Los scripts bash aceptan comandos linux.

Entrada y salida#

  • La salida de datos la ejecutamos con echo y para la entrada hacemos lo siguiente:

 1#!/bin/bash
 2
 3# añadiendo el parámetro n podemos recibir un dato:
 4echo -n "Escribe tu nombre: "
 5# dicho dato lo guardamos en una variable con read:
 6read nombre
 7# Ya podemos utilizar el dato recibido:
 8echo "Te llamas $nombre"
 9
10# alternativamente podemos usar el read directamente para recibir el parámetro con p:
11read -p "Escribe tus apellidos: " apellidos
12
13echo "$nombre $apellidos"

Nota

podemos limitar el número de caracteres de entrada añadiendo un número al parametro -n ej: echo -n8 "Introduce una contraseña de 8 caracteres máximos: "

Nota

añadiendo al echo el parametro -t5 u otro número tardará dicho tiempo en cerrar el programa si no se introduce un valor.

Nota

si usamos en read el parámetro -s ej: read -s password podemos escribir sin que se muestre la información en el prompt.

Pausar ejecución por tiempo#

  • Se puede añadir una pausa con sleep añadiendo un valor numérico que serán los segundos que debe pausarse.

1#!/bin/bash
2
3echo "creando materia oscura..."
4sleep 1
5echo "preparando atomos de carga..."
6sleep 1
7echo "cargando mundo..."
8sleep 2
9echo "LISTO PARA DESPEGAR!"

Recibir parámetros#

cada parámetro se recibe con el símbolo $ seguido de un número siendo $0 el propio script:

1#!/bin/bash
2
3# nombre del script:
4echo "Este es el script ejecutado: $0"
5
6# parametro capturado:
7echo "Parametro capturado: $1"
  • Se ejecuta ./script.sh parametro para ver el resultado.

Nota

se pueden añadir mas de un parámetro.

Ejecución de comandos#

 1#!/bin/bash
 2
 3# comprobamos si no recibimos un parametro:
 4if [ "$1" = "" ]; then
 5        # creamos un ejemplo de uso:
 6        echo "Uso $0 [IP]"
 7        echo "Ejemplo $0 192.168.109.1"
 8else
 9        # si recibimos un parámetro realizamos un escaner de puertos:
10        echo "Se esta realizando el escaneo..."
11        nc -nvz $1 1-65535 > resultado.txt
12fi

Variables y tipos de datos#

Variables#

1#!/bin/bash
2
3# Esto es un comentario
4
5# Declarar una variable:
6nombre="Guillermo"
7
8# Imprimir variables, para usar variables hay que añadir $ al principio:
9echo "Me llamo $nombre" # la interpolación es automática

Atención

El casting de variables no es un problema, ya que las variables son mutables. Por buena practica es importante que cuando se asigne un tipo de dato a una variable no se cambie.

Nota

La interpolación con comillas dobles permite añadir las variables en cualquier de la cadena de texto.

Variables de entorno#

Las variables de entorno se establecen en el sistema y para utilizarlas se usa el comando env.

Las variables de entornos mas destacadas son:

  • echo $HOME: Muestra la ruta del directorio home del usuario.

  • echo $PATH: Muestra una lista de directorios separados por : .

  • echo $LOGNAME: Muestra el usuario logeado.

  • echo $HOSTNAME: Muestra el nombre del equipo.

  • echo $MACHTYPE: Tipo de sistema que estamos utilizando.

  • echo $UID: Muestra el id del usuario activo.

Las variables de entorno se definen en /etc/profile, /etc/profile.d y ~/.bash_profile.

Operadores#

Operadores aritméticos#

 1#!/bin/bash
 2
 3# PARA OPERACIONES ARITMÉTICAS USAMOS LA ASIGNACIÓN DE VARIABLE CON LET
 4let suma=5+5
 5echo "Suma: $suma"
 6
 7let resta=10-2
 8echo "Resta: $resta"
 9
10let multiplicacion=2*8
11echo "Multiplicación: $multiplicacion"
12
13let division=10/2
14echo "División: $division"
15
16let potencia=2**3
17echo "Potencia: $potencia"
18
19let modulo=17%2
20echo "Módulo o resíduo: $modulo"

Atención

Recuerda que la asignación de datos en BASH no debe tener espacios entre el símbolo =

Operadores relacionales#

Validación entre dos números.

  • -eq : Igual que.

  • -ge : Mayor o igual que.

  • -le : Menor o igual que.

  • -ne : Diferente que.

  • -gt : Mayoer que.

  • -lt : Menor que.

Operadores lógicos#

Expresiones de operaciones lógicas.

  • = : Igual que.

  • != : Diferente que.

  • -n : Valida si la cadena es superior a 0.

  • -z : Valida si la cadena es igual a 0.

Comparacion de archivos#

Expresiones para comparar archivos.

Cuando recuperamos un path mediante una cadena:

  • -d: Comprueba si es un directorio.

  • -f: Comprueba si es un archivo.

  • -s: Comprueba si es un link simbólico.

  • -e: Comprueba si el fichero existe.

  • -s: Comprueba si tiene un tamaño mayor a 0.

  • -r: Comprueba si tiene permiso de lectura.

  • -w: Comprueba si tiene permiso de escritura.

  • -x: Comprueba si tiene permiso de ejecución.

Estructuras de control#

Condicional if#

  • If sencillo:

1#!/bin/bash
2
3echo -s "Contraseña: "
4read clave
5
6if [ "$clave"="contraseña" ];
7then
8        echo "Correcto"
9fi
  • If/else:

 1#!/bin/bash
 2
 3echo -n "Introduce tu edad: "
 4read edad
 5
 6if [ "$edad" -ge 18 ];
 7then
 8        echo "Tienes $edad años, eres mayor de edad."
 9else
10        echo "Con $edad, eres menor de edad."
11fi
  • Else-if:

 1#!/bin/bash
 2
 3echo -n "Introduce tu edad: "
 4read edad
 5
 6if [ "$edad" -ge 65 ];
 7then
 8        echo "Con $edad ya eres un ancian@."
 9elif [ "$edad" -ge 18 ];
10then
11        echo "Tienes $edad años, eres mayor de edad."
12else
13        echo "Con $edad, eres menor de edad."
14fi
  • Comprobar archivos:

 1#!/bin/bash
 2
 3echo -n "Introduce una ruta: "
 4read path
 5
 6# validando si es directorio, archivo o enlace simbólico:
 7if [ -d $path ]; then
 8        echo "$path es un directorio"
 9        file="directorio"
10elif [ -f $path ]; then
11        echo "$path es un archivo"
12        file="archivo"
13else
14        echo "$path no existe"
15fi
16
17# validando que permisos tiene:
18if [ -r $path ]; then
19        echo "  - el $file tiene permisos de lectura"
20fi
21
22if [ -w $path ]; then
23        echo "  - el $file tiene permisos de escritura"
24fi
25
26if [ -x $path ]; then
27        echo "  - el $file tiene permisos de ejecución"
28fi

Switch / Case#

En el caso de switch tenemos una estructura similar llamada case:

 1#!/bin/bash
 2
 3echo "¿cuál es tu consola favorita?"
 4echo "
 5        1. Nintendo Switch
 6        2. Playstation 4
 7        3. Playstation 5
 8        4. Xbox Series X/Y
 9"
10echo -n "Introduce un número del 1 al 4: "; read consola
11
12case $consola in
13
14        1)
15                echo "Eres fan de Nintendo!"
16                ;;
17        2|3)
18                echo "Eres fan de Playstation!"
19                ;;
20        4)
21                echo "Eres fan de XBOX!"
22                ;;
23        *)
24                echo "Número introducido no válido"
25                ;;
26esac

Bucle for básico#

1#!/bin/bash
2
3# hacemos el bucle con unos números por defecto:
4for num in {1..10}
5do
6        echo $num
7done

Bucle While#

 1#!/bin/bash
 2
 3echo -n "Introduce la contraseña: "
 4read password
 5
 6while [ $password != "bash"  ]; do
 7        echo -n "Contraseña erronea, vuelve a intentarlo: "
 8        read password
 9done
10
11echo "Bienvenid@ al sistema"

Until#

  • Funciona exactamente igual que while salvo porque se ejecuta hasta que la condición sea false:

 1#!/bin/bash
 2
 3echo -n "Introduce la contraseña: "
 4read password
 5
 6until [ $password = "bash"  ]; do
 7        echo -n "Contraseña erronea, vuelve a intentarlo: "
 8        read password
 9done
10
11echo "Bienvenid@ al sistema"

Tipos de datos avanzados#

Arrays#

 1#!/bin/bash
 2
 3# Asignación individual de valores:
 4consolas[0]="Nintendo Gamecube"
 5consolas[1]="Sony Playstation"
 6consolas[2]="Sega Megadrive"
 7consolas[3]="Nintendo Switch"
 8
 9# Asignación conjunta:
10videojuegos=("The last of Us" "Sonic the Hedgehog" "Crash Bandicoot")
11
12# recorrer elementos por índice:
13for c in {0..3}
14do
15        echo ${consolas[$c]}
16done
17
18# podemos contar todos los valores que tiene un array usando # y luego *:
19echo "Hay ${#videojuegos[*]} videojuegos:"
20
21# BUCLE TIPO C:
22# guardamos la cantidad de valores:
23let total_juegos=${#videojuegos[*]}
24
25# Creamos un bucle for tipo c:
26for(( i=0; $i<$total_juegos; i=$i+1))
27do
28        echo "  - ${videojuegos[$i]}"
29        # vamos a hacer una pausa de 1 segundo:
30        sleep 1
31done

Importante

Los arrays en Bash tienen un máximo de 1024 elementos.

Programación modular#

Funciones#

 1#!/bin/bash
 2
 3# crear una función:
 4function saludar() {
 5        echo "Hola $nombre"
 6        # return (para retornar valores)
 7}
 8
 9# utilizar función saludar:
10echo -n "Introduce tu nombre: "
11read nombre
12
13saludar $nombre

Importar y exportar#

Exportar variables#

Se puede exportar una variable cuando sea necesario utilizar fuera de su ámbito, por ejemplo en otro interpretre dentro del archivo:

 1#!/bin/bash
 2
 3# variables normales y exportadas:
 4var_basica="Variable normal"
 5export var_exportada="Variable exportada"
 6
 7# si ejecutamos un nuevo interpretre y llamamos a ambas solo mostrará el resultado de la exportada:
 8bash -c '
 9echo "valor de var_basica: $var_basica"
10echo "valor de var_exportada: $var_exportada"
11'