Tutorial de Programacion en Bash
Bash es una shell, que ademas 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 interprete de comandos y sabes como hacer guiones simples de programacion, sin dudas este tutorial te ensenara algunas de sus caracteristicas mas avanzadas de Bash.
Variables
Las variables de bash son las mismas que en otros lenguajes de programacion. 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 guion. Las variables locales solo son accesibles dentro del mismo. Por ejemplo, una variable local utilizada unicamente en dentro de una funcion:
#!/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 sera accesible aqui
}
echo $LOCAL_VAR ## Esto no sera accesible aqui
echo $GLOBAL_VAR
Variable de Sistema
Las variables de sistema son responsables de definir aspectos del
interprete de comando Bash. Estas variables son mantenidas por Bash en
si. 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 mayusculas, por
ejemplo: PATH
, SHELL
, HOME
,
LANG
, PWD
y muchas mas.
Citas
En muchos lenguajes de programacion una practica estandar citar la cadena. Las citas se utilizan para referenciar texto, ficheros con caracteres de espacio.
Cita con cadena
No existe diferencia al utilizar apostrofo '...'
o
comillas "..."
mientras operas con textos simples y
cadenas.
El siguiente guion correra sin errores y presentara el mensaje indicado y creara ambos directorios:
#!/usr/local/bin/bash
echo 'Cadena apostrofada'
echo "Cadena entrecomillada"
mkdir 'Directorio 1'
mkdir "Directorio 2"
Citas con Variables
Recuerda que las expansion de variables de Bash unicamente operara con las comillas. Si defines cualquier variable en comillas simples, ¡no funcionaran!
Ejecuta el siguiente guion. La primer echo presentara el valor de la
variable (ej. Bienvenid@ ~fulana
). Pero la segunda variable
solo presentara $NOMBRE
porque esta entre comillas
simples:
#!/usr/local/bin/bash
NOMBRE="Bienvenid@ ~$USER"
echo "$NOMBRE"
echo '$NOMBRE'
Depuracion en Bash
El guionado de Bash provee una funcionalidad de depuracion durante el
tiempo de ejecucion. Emplea el comando set -xv
dentro del
guion o en la linea de comando cuando ejecutes el guion para
depurarlo.
Depurado durante la ejecucion
Utiliza Bash con el argumento -xv
para depurar al tiempo
de ejecucion de un guion de bash:
$ bash -xv guion.sh
Depurado de un guion
Si deseas activar la depuracion dentro del mismo guion, podras depurar cierta parte del guion.
#!/usr/local/bin/bash
set -xv # Esta linea activa el depurado
cd /var/log/
for i in "*.log"; do
du -sh $i
done
Ahora corre el guion...
$ ./guion.sh
...y obtendras 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
Codigo de Salida
Un codigo de salida en Bash es un valor en codigo que representa el resultado de la ejecucion apropiada de un programa, representado por un valor entre 0 y 255. Tal numero denota el status de salida del ultimo comando introducido, en otras palabras, es la indicacion que da - al cese de su ejecucion - el proceso hijo, al retornar al su proceso padre.
0 - Success |
Un valor cero (0) representa exito. |
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 ejecutalo para ver si funciona
correctamente:
#!/usr/local/bin/bash
echo "Viva Bash, mas rapido 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 buscara la cadena fulana
en el fichero
/etc/passwd
.
#!/usr/local/bin/bash
CADENA="fulana"
if grep ${CADENA} /etc/passwd
then
echo "Si! Encontre la cadena"
else
echo "Buu!, no encontre la cadena"
fi
Entrada de Usuario
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
Tambien podras indicar algun texto con -p
, que se
presentara a modo de informacion a la hora de solicitar la entrada:
read -p "Dime tu nombre de usuari@: " tuusuario
Podras utilizar el argumento -sp
para no mostrar lo que
tecleas (util para guardar secreto en pantalla).
$ read -sp "Dime de que equipo eres fanatic@: " tuequipo
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@: " tuusuario
read -sp "Dime en secreto de que equipo eres fanatic@: " tuequipo
echo -e "\nTu nombre de usuari@ es $tuusuario y tu equipo favorito es $tuequipo"
Operadores
Los operadores en unix permiten realizar distinto tipo de operaciones en la shell. Bash cuenta con los mismos operadores, y extiende su utilizacion,
A continuacion encontraras ejemplos de su uso en Bash.
Operadores aritmeticos
En Bash podras encerrar entre parentesis dobles
((...))
para realizar las operaciones aritmeticas sobre
variables constituidas por valores numericos, segun esta sintaxis:
((expresion))
((variable1+variable2))
((variable1-variable2))
((variable1*variable2))
((variable1/variable2))
Ejemplo de operadores aritmeticos
Este guion permite ingresar dos valores numericos para realizar las cinco operaciones basicas:
#!/usr/local/bin/bash
read -p "Ingresa un valor numerico: " n1
read -p "Ingresa otro valor numerico: " n2
echo "La Suma de $n1 + $n2 es = " $((n1+n2))
echo "La Resta de $n1 - $n2 es = " $((n1-n2))
echo "La Division de $n1 / $n2 es = " $((n1/n2))
echo "La Multiplicacion de $n1 * $n2 es = " $((n1*n2))
echo "El modulo entre $n1 % $n2 es = " $((n1%n2))
Operadores de comparacion 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 comparacion numerica
Como en todos los shells de tipo Unix, en Bash podras utilizar operadores de comparacion numerica.
((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 tambien 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
Condicionales
En un lenguaje de programacion se utilizan bucles para repetir la
ejecucion de un bloque de codigo hasta que se satisfaga una condicion
definida. Esto es sumamente util 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 introduccion, nudo y desenlace. Introducen con su identificador, y desenlazan con un identificador inverso.
If-Else
Al igual que cualquier otro lenguaje de programacion,
if-else
es la declaracion de toma de decisiones de Bash.
Decidira la ejecucion de un bloque de codigo en base al resultado del
condicional if
. Si se evalua verdadera la condicion,
ejecutara el codigo. Si la evalua falsa, se ejecutara 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 funcion 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 numerico: " mivariable
if [ $mivariable -gt 10 ]
then
echo "El valor es mayor que 10"
fi
Ejemplos If-else
Usando la declaracion if-else ("si-ademas"), es posible
ejecutar una declaracion condicional si esta resulta falsa. Para ello se
define un bloque de texto con else
.
Este ejemplo implica un condicional por comparacion numerica. Dara
Verdadero si el valor ingresado por el usuario es mayor a
10
, y si cumple tal prerrogativa ("then", "luego")
presentara Correcto
; luego si ademas resulta
Falso (de aqui el "if-else"), presentara
No es correcto
.
#!/usr/local/bin/bash
read -p "Ingresa una cifra: " mivariable
if [ $mivariable -gt 10 ]
then
echo "Correcto"
else
echo "No es correcto"
fi
Este ejemplo realiza una comparacion 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 condicion elif (else-if, "si ademas") se usa para
incorporar multiples condicionales if
.
En este ejemplo de condicioniales else-if, debes indicar tus
calificaciones. Si son mayores o iguales a 80
, presentara
Muy satisfactorio
. Si son inferiores a 80
o
igual a 50
presentara Satisfactorio
,
etcetera.
#!/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 "Aun no satisfactorio"
else
echo "Insatisfactorio"
Ejemplo de condicionales if anidados
Con los if anidados, solo se comprobara la veracidad de una condicion anidada, si otra condicion nido resulta verdadera.
Por ejemplo, este programa solicita ingresar 3 valores numericos como entrada y realiza una comparacion numerica para analizar cual es el valor mayor.
#!/usr/local/bin/bash
read -p "Cuantas copas tiene Boca :" copasboca
read -p "Cuantas copas tiene River :" copasriver
read -p "Cuantas copas tiene Independiente :" copasindependiente
if [ $copasboca -gt $copasriver ]
then
if [ $copasboca -gt $copasindependiente ]
then
echo "Boca es el mas grande"
else
echo "Independiente es el Rey de Copas"
fi
else
if [ $copasriver -gt $copasindependiente ]
then
echo "River es el mas grande"
else
echo "Independiente es el Rey de Copas"
fi
fi
While
While es una estructura de control de bucle iterativo, que continua ciclando ("iterando") hasta que el condicional suministrado de 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 funcion
condicional until
("hasta"), que continuara iterando hasta
que se valide el condicional. Tambien puede incorporar la accion
break
("interrumpir"), con la sintaxis general:
while condicion
do
paso1
paso2
...
done
Ejemplo de bucle While
El siguiente bucle se ejecutara 5 veces y se detendra 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 tambien 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 saldra del bucle.
En este ejemplo, se utiliza un condicional para ingresar a traves de
read cualquier cadena y valor, resenta un mensaje con
echo y utiliza la orden read
para solicitar
interaccion del usuario a traves del teclado). Solo interrumpira el
bucle de solicitud condicional si se se introduce s
o bien
(indicado con -o S
), con lo cual
interrumpira 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 tambien 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 util de bash permite que el bucle While lea el contenido de un fichero linea por linea. De esta forma se puede leer lineas y desarrollar alguna tarea:
#!/bin/bash
while read mivariable
do
echo $mivariable
done < /tmp/mi_fichero.txt
En este ejemplo el se leera en bucle linea a linea de
nombre_fichero.txt
y asignara el valor a la variable
mivariable
.
Ver tambien: while.sh (ejemplo
while-do-done
))
Until
Until, es una instruccion de control que sirve para generar
bucles, en los cuales grupos de instrucciones anidadas dentro de un
bloque se ejecutan de forma repetida hasta que se cumpla una condicion.
Sigue la sintaxis until-do-done
.
Cabe destacar que Until, primero comprobara si se cumple la condicion y si se cumple y solo si se cumple entonces finaliza la secuencia de las instrucciones contenidas entre do y done.
Cada vez que se ejecuta un bucle completo (paso de bucle) vuelve a verificar si se cumple la condicion antes de volver a ejecutar otro paso de bucle.
Ejemplo Until-do-done
until [ "condicion logica" ]
do
accion 1
accion 2
accion n
done
do y done
Las acciones entre do
y done
se repetiran
secuencialmente hasta que se cumpla la "condicion logica". Cuando la
"condicion logica" sea verdadera, no se ejecutara ninguna "accion" y
finalizara el bucle.
Ejemplo Do-Done
<limite=5
i=10;
until [ $limite -gt $i ]
do
echo Accion $i ejecutada
let i=$i-1
done
El ejemplo anterior mostraria por pantalla:
Accion 10 ejecutada
Accion 9 ejecutada
Accion 8 ejecutada
Accion 7 ejecutada
Accion 6 ejecutada
Accion 5 ejecutada
case
case ("En caso") permite delimitar casos de condicionales.
La introduccion es case
, el nudo incorpora el caso, que
deben definirse en una linea aislada delimitados por un )
.
Si indicas los casos separados por un |
significa "o
tambien". Un caso nomenclado con *)
indica se interpreta
como "todos los demas". Cada caso debe contar con un separador de linea
;;
. El desenlace es esac
.
Ejemplo de multiples cadenas en case
Se pueden definir mas de una cadena para el patron de coincidencias en una declaracion case.
user=`whoami` # pone el nombre de usuari@ en
# la variable $user.
case $user in
fulana)
echo "Hola fulana. Se 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 Liberacion, y recuerda!"
fortune doctrina
;;
esac
La declaracion case es mas util y rapida para procesar que un condicional else-if. En lugar de revizar todas las condiciones if-else, la declaracion 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 []
. Aun
asi, algunas de las expansiones no funcionaran.
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"
#Aqui va un guion
;;
b?) ### coincide cualquier cadena de dos caracteres que comience con "b"
#Aqui va otro guion
;;
s[td]) ### coincide "st" o "sd"
#Aqui va otro guion
;;
r[ao]m) ### coincide "ram" o "rom"
#Aqui va otro guion
;;
me?(e)t) ### coincide "met" or "meet"
#Aqui va otro guion
;;
@(a|e|i|o|u)) ### coincide una vocal
#Aqui va otro guion
;;
*) ### Coincide todo lo que no coincidio anteriormente
#Aqui va un guion
;;
esac
Bucle for
El bucle for se utiliza para realizar tareas repetitivas. La sintaxis basica de un bucle for, es la siguiente:
for VARIABLE in PARAMETRO1 PARAMETRO2 PARAMETRO3
do
//declaraciones del bucle for-loop
done
El bucle for ejecutara todos los parametros 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 parametros pueden ser cualquier numero, cadena,
etcetera.
Ejemplo Bucle For
Este bucle basico itera 5 veces.
#!/usr/local/bin/bash
for i in 1 2 3 4 5
do
echo "$i"
done
Tambien puedes definir un rango para el bucle for,
utilizando valores numericos entre parentesis ()
dentro del
guion 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 tambien puedes escribir un bucle for siguiendo
nomenclatura de estilo C. Por ejemplo, para presentar numeros 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 iterara la cantidad de veces coincidente con el numero de ficheros disponibles en el directorio de trabajo. Seleccionara un fichero por cada iteracion numerica.
#!/usr/local/bin/bash
for nombrefichero in *
do
ls -l $nombrefichero
done
Ver tambien: manzanas.sh
(Ejemplo bucle for-if
)
Funciones
Una funcion (tambien llamadas subrutinas o procedimientos) es una seccion de codigo utilizada para realizar una tarea especifica. Estas pueden ser reutilizadas.
Sintaxis:
nombreFuncion(){
// procedimiento de la funcion
}
nombreFuncion //llamada a la funcion
Creacion de una funcion
Crea tu primer funcion de un guion de bash para que presente la cadena "Hola Texto-plano.xyz!". Elabora el guion de Shell "saludo.sh" con el siguiente codigo fuente:
#!/usr/local/bin/bash
funSaludazo(){
echo "¡Hola texto-plano.xyz!";
}
# llama a la funcion saludazo desde cualquier lugar del guion, por ejemplo, ahora mismo:
funSaludazo
Ejecuta el guion creado:
$ ./saludo.sh
¡Hola texto-plano.xyz!
Funcion con argumento
Para indicarle un argumento a la funcion es necesario hacerlo de la
misma manera que argumentarias cualquier comando desde el interprete de
comandos: agregandolos a continuacion con un espacio en blanco. Las
funciones reciben argumentos $1
, $2
, etcetera.
En consecuencia, para crear un guion de shell con argumento podrias
incluir un codigo 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 parametros como los indicados a continuacion
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