tutorial_de_programacion_en_bash

Bash es una shell, que además cuenta con un lenguaje de comandos interpretado incorporado. Esto te permite escribir guiones y correrlos directamente en tu entorno.

Si ya has completado el primer Tutorial del lenguaje de intérprete de comandos y sabes cómo hacer guiones simples de programación, sin dudas este tutorial te enseñará algunas de sus características más avanzadas de Bash.

Las variables de bash son las mismas que en otros lenguajes de programación. No necesita especificarlas.

#!/usr/local/bin/bash
 
NAME="Tutoriales texto-plano.xyz"
echo $NAME
 
launchdate="Feb 28, 2023"
echo $launchdate

Varibles Globales y Locales

Las Variables Globales son accesibles desde cualquier lugar del guión. Las variables locales sólo son accesibles dentro del mismo. Por ejemplo, una variable local utilizada unicamente en dentro de una función:

#!/usr/local/bin/bash
 
#Define una variable global de bash 
GLOBAL_VAR="valor de variable global"
 
function hola {
    #Define variable local de bash
    local LOCAL_VAR="valor de variable local"
    echo $LOCAL_VAR
    echo $GLOBAL_VAR    ## Esto será accesible aquí
}
echo $LOCAL_VAR     ## Esto no será accesible aquí
echo $GLOBAL_VAR

Variable de Sistema

Las variables de sistema son responsables de definir aspectos del intérprete de comando Bash. Estas variables son mantenidas por Bash en sí. Podremos modificar tales variables para cambiar aspectos del Shell. Utiliza el comando env para presentar todas las variables disponibles de Bash.

env

Generalmente se suele definir estas variables en mayúsculas, por ejemplo: PATH, SHELL, HOME, LANG, PWD y muchas mas.

En muchos lenguajes de programación una práctica estándar citar la cadena. Las citas se utilizan para referenciar texto, ficheros con caracteres de espacio.

Cita con cadena

No existe diferencia al utilizar apóstrofo '...' o comillas “…” mientras operas con textos simples y cadenas.

El siguiente guion correrá sin errores y presentará el mensaje indicado y creará ambos directorios:

#!/usr/local/bin/bash
 
echo 'Cadena apostrofada'
echo "Cadena entrecomillada"
 
mkdir 'Directorio 1'
mkdir "Directorio 2"

Citas con Variables

Recuerda que las expansión de variables de Bash únicamente operará con las comillas. Si defines cualquier variable en comillas simples, ¡no funcionarán!

Ejecuta el siguiente guion. La primer echo presentará el valor de la variable (ej. Bienvenid@ ~fulana). Pero la segunda variable solo presentará $NOMBRE porque está entre comillas simples:

#!/usr/local/bin/bash
 
NOMBRE="Bienvenid@ ~$USER"
 
echo "$NOMBRE"
echo '$NOMBRE'

El guionado de Bash provee una funcionalidad de depuración durante el tiempo de ejecución. Emplea el comando set -xv dentro del guion o en la línea de comando cuando ejecutes el guion para depurarlo.

Depurado durante la ejecución

Utiliza Bash con el argumento -xv para depurar al tiempo de ejecución de un guión de bash:

$ bash -xv guion.sh

Depurado de un guión

Si deseas activar la depuración dentro del mismo guion, podrás depurar cierta parte del guion.

#!/usr/local/bin/bash
 
set -xv   # Esta línea activa el depurado
 
cd /var/log/
for i in "*.log"; do
 du -sh $i
done

Ahora corre el guion…

$ ./guion.sh

…y obtendrás resultados como:

cd /var/log/
+ cd /var/log/
for i in "*.log"; do
 du -sh $i
done
+ for i in '"*.log"'
+ du -sh boot.log mysqld.log post111.log post1121.log yum.log
0       boot.log
32K     mysqld.log
0       post111.log
0       post1121.log
4.0K    yum.log

Un código de salida en Bash es un valor en código que representa el resultado de la ejecución apropiada de un programa, representado por un valor entre 0 y 255. Tal número denota el status de salida del último comando introducido, en otras palabras, es la indicación que da - al cese de su ejecución - el proceso hijo, al retornar al su proceso padre.

0 - Success Un valor cero (0) representa éxito.
1-255 Failure Un valor no cero representa un fracaso.

Ejemplo

Escribe un programa para escribir una cadena de texto en /etc/fichero_prueba.txt y ejecútalo para ver si funciona correctamente:

#!/usr/local/bin/bash
 
echo "Viva Bash, más rápido que un flash!" > /tmp/fichero_prueba.txt
 
if [ $? -eq 0 ]; then
  echo "Funciona! Viva el Software Libre!"
else
  echo "Lo siento, no puedo escribir en /tmp/fichero_prueba.txt"
fi

Este fichero buscará la cadena fulana en el fichero /etc/passwd.

#!/usr/local/bin/bash
 
STRING="fulana"
 
if grep ${STRING} /etc/passwd
then
  echo "Si! Encontré la cadena"
else
  echo "Buu!, no encontré la cadena"
fi

El comando read se utiliza realizar entrada de datos interactiva.

Para que el sistema aguarde tu entrada y la almacene en una variable al presionar la tecla Intro es la siguiente:

$ read mivariable

También podrás indicar algún texto que se presentará a modo de información, a la hora de solicitar la entrada:

read -p "Dime tu nombre de usuari@: " miusuario

Podrás utilizar el argumento -sp para no mostrar lo que tecleas (útil para guardar secreto en pantalla).

$ read -sp "Dime de que equipo eres fanátic@: " miequipo

Utiliza en un guion de Bash la funcionalidad del comando read para solicitar el ingreso de datos al usuario:

#!/usr/local/bin/bash
 
read -p "Ingresa tu nombre de usuari@: " miusuario
read -sp "Dime de qué equipo eres fanátic@: " miequipo
 
echo -e "\nTu nombre de usuari@ es $miusuario y tu equipo favorito es $miequipo"

Los operadores en unix permiten realizar distinto tipo de operaciones en la shell. Bash cuenta con los mismos operadores, y extiende su utilización,

A continuación encontrarás ejemplos de su uso en Bash.

Operadores aritméticos

En Bash podrás encerrar entre paréntesis dobles (()) para realizar las operaciones aritméticas sobre variables constituidas por valores numéricos, según esta sintaxis:

(expresion))
(variable1+variable2))
(variable1-variable2))
(variable1*variable2))
(variable1/variable2))
Ejemplo de operadores aritméticos

Este guion permite ingresar dos valores numéricos para realizar las cinco operaciones básicas:

#!/usr/local/bin/bash
 
read -p "Ingresa un valor numérico: " n1
read -p "Ingresa otro valor numérico: " n2
 
echo "La Suma de $n1 + $n2 es       = " $((n1+n2))
echo "La Resta de $n1 - $n2 es    = " $((n1-n2))
echo "La División de $n1 / $n2 es       = " $((n1/n2))
echo "La Multiplicación de $n1 * $n2 es = " $((n1*n2))
echo "El módulo entre $n1 % $n2 es        = " $((n1%n2))

Operadores de comparación de cadena

Utiliza doble igual (==) para comparar cadenas.

if [ "$cadena" == "$cadena2" ]     # True si es igual
if [ "$cadena1" != "$cadena2" ]     # True si es no igual

Operadores de comparación numérica

Como en todos los shells de tipo Unix, en Bash podrás utilizar operadores de comparación numérica.

((n1 == n2))    ## n1 es igual a n2
((n1 != n2))    ## n1 es no igual a n2
((n1 > n2))     ## n1 es mayor a n2
((n1 >= n2))    ## n1 es mayor o igual a n2
((n1 < n2))     ## n1 es menor a n2
((n1 <= n2))    ## n1 es menor o igual a n2

Operadores de incremento y decremento

Bash también cuenta con operadores de incremento (++) y decremento (<nowiki>–</nowiki. Ambos usos en dos tipos de pre-incremento/post-incremento y pre-decremento/post-decremento.

## Ejemplo de Post-incremento
$ variable=10
$ echo $((variable++))  ## Primero imprime 10 luego incrementa valor en 1
 
## Ejemplo de Pre-incremento
$ variable=10
$ echo $((++variable))  ## Primero incrementa valor en 1 luego imprime 11 

En forma similar, puedes utilizar operadores de pre-decremento y operadores de post-decremento.

## Ejemplo de Post-decremento
$ variable=10
$ echo $((variable--))  ## Primero imprime 10 y luego decrementa el valor en 1
 
## Ejemplo de Pre-decremento
$ variable=10
$ echo $((--variable))  ## Primero decrementa el valor en 1 luego imprime 9

En un lenguaje de programación se utilizan bucles para repetir la ejecución de un bloque de código hasta que se satisfaga una condición definida. Esto es sumamente útil para realizar tareas repetitivas. Existen tres tipos de bucles principales: for (en caso), do (“hacer”), y do-while (“hacer-en tanto”).

Las condiciones cuentan con introducción, nudo y desenlace. Introducen con su identificador, y desenlazan con un identificador inverso.

Al igual que cualquier otro lenguaje de programación, if-else es la declaración de toma de decisiones de Bash. Decidirá la ejecución de un bloque de código en base al resultado del condicional if. Si se evalúa verdadera la condición, ejecutará el código. Si la evalúa falsa, se ejecutará el bloque else, cuya existencia es opcional.

Se abre con if e incorpora la llamada then y se cierra con fi. Opcionalmente, en el nudo puede incorporar una función condicional else, con la sintaxis general:

if [ condicion ]
then
  hacer-algo
else
  hacer-otra-cosa
fi

Ejemplo if-then

Este programa solicita que ingreses una cifra, y te informa si es mayor a 10.

#!/usr/local/bin/bash
 
read -p "Ingrese un valor numérico: " myvar
 
if [ $myvar -gt 10 ]
then
    echo "El valor es mayor que 10"
fi

Ejemplos If-else

Usando la declaración if-else (“si-además”), es posible ejecutar una declaración condicional si esta resulta falsa. Para ello se define un bloque de texto con else.

Este ejemplo implica un condicional por comparación numérica. Dará Verdadero si el valor ingresado por el usuario es mayor a 10, y si cumple tal prerrogativa (“then”, “luego”) presentará Correcto; luego si además resulta Falso (de aquí el “if-else”), presentará No es correcto.

#!/usr/local/bin/bash
 
read -p "Ingresa una cifra: " myvar
 
if [ $myvar -gt 10 ]
then
    echo "Correcto"
else
    echo "No es correcto"
fi

Este ejemplo realiza una comparación de cadenas y las compara:

#!/bin/bash
 
read -p "Ingresa la primer cadena: " cadena1
read -p "Ingresa la segunda cadena: " cadena2
if [ "$cadena1" == "$cadena2" ]
then
  echo "Ambas cadenas son iguales"
else
  echo "Ambas cadenas son diferentes"
fi

Ejemplo if-elif-else

La condición elif (else-if, “si además”) se usa para incorporar múltiples condicionales if.

En este ejemplo de condicioniales else-if, debes indicar tus calificaciones. Si son mayores o iguales a 80, presentará Muy satisfactorio. Si son inferiores a 80 o igual a 50 presentará Satisfactorio, etcétera.

#!/usr/local/bin/bash
 
read -p "Ingresa tus calificaciones: " calificacion
 
if [ $calificacion -ge 80 ]
then
    echo "Muy satisfactorio"
 
elif [ $calificacion -ge 50 ]
then
    echo "Satisfactorio"
 
elif [ $calificacion -ge 33 ]
then
    echo "Aún no satisfactorio"
else
    echo "Insatisfactorio"

Ejemplo de condicionales if anidados

Con los if anidados, sólo se comprobará la veracidad de una condición anidada, si otra condición nido resulta verdadera.

Por ejemplo, este programa solicita ingresar 3 valores numéricos como entrada y realiza una comparación numérica para analizar cuál es el valor mayor.

#!/usr/local/bin/bash
 
read -p "Cuantas copas tiene Boca :" boca
read -p "Cuantas copas tiene River :" river
read -p "Cuantas copas tiene Independiente :" independiente
 
if [ $boca -gt $river ]
then
    if [ $boca -gt $independiente ]
    then
        echo "Boca es el más grande"
    else
        echo "Independiente es el Rey de Copas"
    fi
else
    if [ $river -gt $independiente ]
    then
        echo "River es el más grande"
    else
 echo "Independiente es el Rey de Copas"
    fi
fi

While es una estructura de control de bucle iterativo, que continúa ciclando (“iterando”) hasta que el condicional suministrado dé falso.

Se abre con while (“mientras”) e incorpora la llamada do (“hacer”) y se cierra con done (“realizado”). Opcionalmente, en el nudo puede incorporar una función condicional until (“hasta”), que continúará iterando hasta que se valide el condicional. También puede incorporar la acción break (“interrumpir”), con la sintaxis general:

while condición
do
  paso1
  paso2
  ...
done

Ejemplo de bucle While

El siguiente bucle se ejecutará 5 veces y se detendrá cuando el valor de la variable num sea mayor que 5.

#!/bin/bash
 
num=1
while [ $num -le 5 ]
do
   echo "$num"
   let num++
done

Ejemplo de bucle While infinito

Los bucles infinitos se ejecutan continuamente hasta que se detienen forzadamente por el usuario, presionando Ctrl+c.

#!/usr/local/bin/bash
 
while true
do
  echo "Presione Ctrl+c para Salir"
done

Los bucles infinitos también pueden detenerse agregando alguna salida condicional al guion:

#!/usr/local/bin/bash
 
while true
do
   if [condicion];then
      exit
   fi
done

En el caso anterior, cuando la condicion se convierta en verdadera, se saldrá del bucle.

En este ejemplo, se utiliza un condicional para ingresar a través de read cualquier cadena y valor, resenta un mensaje con echo y utiliza la orden read para solicitar interacción del usuario a través del teclado). Sólo interrumpirá el bucle de solicitud condicional si se se introduce s o bien (indicado con -o S), con lo cual interrumpirá el bucle:

while true
do
    echo "Introduce algo para procesar (ingresa S para salir)"
    read entradausuario
 
    if [ $entradausuario == "s" -o $entradausuario == "S" ]
  then
    break
fi
 
//Procesar lo ingresado...
done

Ejemplo de Bucle While de estilo C

Bash también acepta nomenclatura similar a C para escribir un bucle while:

#!/usr/local/bin/bash
 
num=1
while((num <= 5))
do
   echo $num
   let num++
done

Ejemplo de bucle While leyendo fichero

Esta funcionalidad útil de bash permite que el bucle While lea el contenido de un fichero línea por línea. De esta forma se puede leer líneas y desarrollar alguna tarea:

#!/bin/bash
 
while read mivariable
do
   echo $mivariable
done < /tmp/mi_fichero.txt

En este ejemplo el se leerá en bucle línea a línea de nombre_fichero.txt y asignará el valor a la variable mivariable.

case (“En caso”) permite delimitar casos de condicionales.

La introducción es case, el nudo incorpora el caso, que deben definirse en una línea aislada delimitados por un ). Si indicas los casos separados por un | significa “o también”. Un caso nomenclado con *) indica se interpreta como “todos los demás”. Cada caso debe contar con un separador de línea ;;. El desenlace es esac.

Ejemplo de múltiples cadenas en case

Se pueden definir más de una cadena para el patrón de coincidencias en una declaración case.

user=`whoami` # pone el nombre de usuari@ en 
              # la variable $user.
case $user in
    fulana)
      echo "Hola fulana. Sé que te gusta saber la hora, de modo que te la presento abajo."
      date
;;
    sultano)
      echo "Hola Sultano, recuerda tu lista de tareas pendientes."
      cat /home/sultano/sultano_to_do.txt
;;
    sosa|molina)
       echo "Hola. No olvides vigilar la carga en el sistema. El tiempo de encendido del mismo es:"
       uptime
;;
    *)
       echo "Hola, quien quiera que seas. ¡Ponte a obrar por la Liberación, y recuerda!"
       fortune doctrina
;;
esac
La declaración case es más útil y rápida para procesar que un condicional else-if. En lugar de revizar todas las condiciones if-else, la declaración case selecciona directamente el bloque a ejecutar basada en una entrada condicional.

Ejemplo de coincidencia de patrones en case

En las declaraciones case puedes utilizar caracteres comodines como *, ? y []. Aún así, algunas de las expansiones no funcionarán.

Ahora puedes utilizar shopt -s extglob para emplear coincidencia de patrones avanzada.
#!/usr/local/bin/bash
 
read -p "Ingresa una cadena:" choice
shopt -s extglob
case $choice in
     a*)                    ### coincide todo lo que comience con "a"
          #Aquí va un guion
          ;;
 
     b?)                    ### coincide cualquier cadena de dos caracteres que comience con "b"
          #Aquí va otro guion
          ;;
 
     s[td])                 ### coincide "st" o "sd"
          #Aquí va otro guion
          ;;
 
     r[ao]m)                ### coincide "ram" o "rom"
          #Aquí va otro guion
          ;;
 
     me?(e)t)               ### coincide "met" or "meet"
          #Aquí va otro guion
          ;;
 
     @(a|e|i|o|u))          ### coincide una vocal
          #Aquí va otro guion
          ;;
 
     *)                     ### Coincide todo lo que no coincidió anteriormente
          #Aquí va un guion
          ;; 
esac

El bucle for se utiliza para realizar tareas repetitivas. La sintaxis básica de un bucle for, es la siguiente:

for VARIABLE in PARAMETRO1 PARAMETRO2 PARAMETRO3
do
  //declaraciones del bucle for-loop
done 

El bucle for ejecutará todos los parámetros definidos una vez. El nudo del bucle se comienza con la palabra reservada do (“hacer”) y se termina con la palabra reservada done (“finalizado”). Todas las declaraciones deben escribir dentro del nudo del bucle.

En esta sintaxis, VARIABLE se inicializa con los valores del PARAMETRO que puede ser accedido dentro del nudo del bucle. Estos parámetros pueden ser cualquier número, cadena, etcétera.

Ejemplo Bucle For

Este bucle básico itera 5 veces.

#!/usr/local/bin/bash
 
for i in 1 2 3 4 5
do
   echo "$i"
done

También puedes definir un rango para el bucle for, utilizando valores numéricos entre paréntesis () dentro del guión de Bash.

#!/usr/local/bin/bash
 
for i in {1..5}
do
   echo "$i"
done

Los argumentos pueden estar formados por cadenas, como en:

#!/usr/local/bin/bash
 
for dia in DOM LUN MAR MIE JUE VIE SAB DOM
do
   echo "$dia"
done

Ejemplo de Bucle For en estilo C

En Bash es posible también puedes escribir un bucle for siguiendo nomenclatura de estilo C. Por ejemplo, para presentar números del 1 al 10.

#!/usr/bin/bash
 
for ((i=1; i<=10; i++))
do
  echo "$i"
done

Ejemplo de bucle For con ficheros

Puedes acceder nombres de ficheros de uno en uno en un bucle for en el directorio especificado.

Por ejemplo, podremos leer todos los ficheros del directorio de trabajo actual. En el siguiente bucle iterará la cantidad de veces coincidente con el número de ficheros disponibles en el directorio de trabajo. Seleccionará un fichero por cada iteración numérica.

#!/usr/local/bin/bash
 
for nombrefichero in *
do
  ls -l $nombrefichero
done

Una función (también llamadas subrutinas o procedimientos) es una sección de código utilizada para realizar una tarea específica. Estas pueden ser reutilizadas.

Sintaxis:

nombreFuncion(){    
  // procedimiento de la función
}
 
nombreFuncion  //llamada a la función

Creación de una función

Crea tu primer función de un guion de bash para que presente la cadena “Hola Texto-plano.xyz!”. Elabora el guion de Shell “saludo.sh” con el siguiente código fuente:

#!/usr/local/bin/bash
 
funSaludazo(){
    echo "¡Hola texto-plano.xyz!";
}
 
# llama a la función saludazo desde cualquier lugar del guion, por ejemplo, ahora mismo:
 
funSaludazo

Ejecuta el guion creado:

$ ./saludo.sh
¡Hola texto-plano.xyz!

Función con argumento

Para indicarle un argumento a la función es necesario hacerlo de la misma manera que argumentarías cualquier comando desde el intérprete de comandos: agregándolos a continuación con un espacio en blanco. Las funciones reciben argumentos $1, $2, etcétera. En consecuencia, para crear un guion de shell con argumento podrías incluir un código semejante a este:

#!/usr/local/bin/bash
 
funArgumentos(){
   echo "Primer Argumento: " $1
   echo "Segundo Argumento: " $2
   echo "Tercer Argumento: " $3
   echo "Cuarto Argumento: " $4
}
 
# Llama a funArgumentos desde cualquier lugar en el guion, utilizando parámetros como los indicados a continuación
 
funArgumentos 1 Bienvenido a Texto-plano.xyz 

Ejecuta el guion desde la shell de Bash:

$ ./saludo.sh
Primer Argumetno : 1
Segundo Argumento : Bienvenido
Tercer Argumento : a
Cuarto Argumento : Texto-plano.xyz
  • tutorial_de_programacion_en_bash.txt
  • Última modificación: 2023/06/06 18:27
  • por peron