Bash scripting
Carpeta con scripts
Para realizar este post vamos a crear una carpeta donde vamos a guardar todos los scripts
!mkdir scripts_bash
Primer script
Especificación del binario de ejecución
En linux se puede indicar con qué programa ejecutar un archivo poniendo en la primera linea #!<ruta binario>
, por ejemplo, si creamos un .py
podemos indicar que se tiene que ejecutar con python poniendo en la primera linea #!/usr/bin/python3
. En nuestro, como estamos haciendo un script de la terminal ponemos en la primera linea #!/bin/bash
.
Ahora si se le dan permisos de ejecución al archivo, se puede ejecutar directamente sin indicar el programa con el que se tiene que ejecutar. Es decir, el .py
ya no necesita ser ejecutado mediante python script.py
, sino que se puede ejecutar mediante .script.py
. En nuestro caso, en vez de ejecutar el archivo mediante bash script.sh
podemos ejecutarlo mediante ./script.sh
Comentarios en scripts de bash
Si queremos introducir un comentario bastaría con empezar la linea con #
.
# Esto es un comentario de una sola línea
Si lo que queremos es introducir varias líneas de comentarios tenemos que empezar con : '
y terminar con '
: '
Este es un comentario de varias líneas
que se extiende a través de varias líneas.
'
Imprimir por pantalla con el comando echo
Si queremos imprimir por pantalla utilizamos el comando echo
seguido de lo que queramos imprimir
!mkdir scripts_bash%%writefile scripts_bash/01_primerScript.sh#!/bin/bash# Comentario de una sola linea: 'Comentario de variaslineas'echo "Hola mundo"
Writing scripts_bash/01_primerScript.sh
Damos permisos de ejecución y ejecutamos el script
!chmod +x scripts_bash/01_primerScript.sh && ./scripts_bash/01_primerScript.sh
Hola mundo
Declaración de variables
Hay dos tipos de variables, las variables de usuario
y las variables de entorno
Para crear una variable basta con declararla introduciendo el nombre que queremos, seguido de =
y el valor
Para imprimir el valor de una variable con echo
, se tiene que referenciar a ella mediante `$
echo "Variable = $<nombre de variable>
%%writefile scripts_bash/02_variables.sh#!/bin/bashopcion=1nombre="Juan"echo "Opcion: $opcion"echo "Nombre: $nombre"
Writing scripts_bash/02_variables.sh
!chmod +x scripts_bash/02_variables.sh && ./scripts_bash/02_variables.sh
Opcion: 1Nombre: Juan
Alcande de las variables
Las variables creadas solo son accesibles desde el script, es decir, su alcance es dentro del script
Exportación de variables
Podemos exportar variables para que estén accesibles por otros scrips, para ello primero exportamos la variable mediante el comando export
y ejecutamos llamamos, dentro del script, al segundo script al que se le quiere pasar la variable
%%writefile scripts_bash/02_variables.sh#!/bin/bashopcion=1nombre="Juan"echo "Opcion: $opcion"echo "Nombre: $nombre"# Exportar variable nombreecho "export nombre=$nombre"export nombre# Ejecutar script de importacionecho ""echo "Ejecutando script de importacion"./scripts_bash/02_variables_importacion.sh
Overwriting scripts_bash/02_variables.sh
%%writefile scripts_bash/02_variables_importacion.sh#!/bin/bashecho "Nombre importado: $nombre"
Writing scripts_bash/02_variables_importacion.sh
!chmod +x scripts_bash/02_variables.sh && chmod +x scripts_bash/02_variables_importacion.sh && ./scripts_bash/02_variables.sh
Opcion: 1Nombre: Juanexport nombre=JuanEjecutando script de importacionNombre importado: Juan
Se tiene que ejecutar el segundo script dentro del primer script. Si ahora ejecutamos el segundo script no tenemos la variable
!chmod +x scripts_bash/02_variables_importacion.sh && ./scripts_bash/02_variables_importacion.sh
Nombre importado:
Si queremos que sea accesible desde cualquier un segundo script, sin tener que ejecutarlo dentro del primer scritp, tenemos que exportar la variable a una variable de entorno
Tipos de operadores
A continuación mostramos todos los posibles operadores
%%writefile scripts_bash/03_operadores.sh#!/bin/bash# Asignación de variablesx=10y=20echo "x = $x"echo "y = $y"# Operadores aritméticosecho ""echo "Operadores aritméticos"echo "x + y = $((x + y))"echo "x - y = $((x - y))"echo "x * y = $((x * y))"echo "x / y = $((x / y))"echo "x % y = $((x % y))"# Operadores de comparaciónecho ""echo "Operadores de comparación"if [ "$x" -eq "$y" ]; thenecho "x es igual a y"elseecho "x no es igual a y"fiif [ "$x" -ne "$y" ]; thenecho "x no es igual a y"elseecho "x es igual a y"fiif [ "$x" -lt "$y" ]; thenecho "x es menor que y"elseecho "x no es menor que y"fiif [ "$x" -gt "$y" ]; thenecho "x es mayor que y"elseecho "x no es mayor que y"fi# Operadores de cadenaecho ""echo "Operadores de cadena"if [ "$a" = "$b" ]; thenecho "a es igual a b"elseecho "a no es igual a b"fiif [ "$a" != "$b" ]; thenecho "a no es igual a b"elseecho "a es igual a b"fiif [ -z "$a" ]; thenecho "a es una cadena vacía"elseecho "a no es una cadena vacía"fiif [ -n "$a" ]; thenecho "a no es una cadena vacía"elseecho "a es una cadena vacía"fi# Operadores de archivoecho ""echo "Operadores de archivo"if [ -e "/path/to/file" ]; thenecho "El archivo existe"elseecho "El archivo no existe"fiif [ -f "/path/to/file" ]; thenecho "Es un archivo regular"elseecho "No es un archivo regular"fiif [ -d "/path/to/dir" ]; thenecho "Es un directorio"elseecho "No es un directorio"fi
Overwriting scripts_bash/03_operadores.sh
!chmod +x scripts_bash/03_operadores.sh && ./scripts_bash/03_operadores.sh
x = 10y = 20Operadores aritméticosx + y = 30x - y = -10x * y = 200x / y = 0x % y = 10Operadores de comparaciónx no es igual a yx no es igual a yx es menor que yx no es mayor que yOperadores de cadenaa es igual a ba es igual a ba es una cadena vacíaa es una cadena vacíaOperadores de archivoEl archivo no existeNo es un archivo regularNo es un directorio
Paso de argumentos
Se pueden pasar argumentos a los scrips, una vez dentro del script podemos hacer uso de ellos de la siguiente manera
- Por número de argumento: en este caso se nombrarán como
$1
,$2
, etc. Pero en caso de que el número de argumentos sea mayor que 9, es decir que haga falta más de 2 dígitos para nombrarlo, en ese caso se identificará el número entre llaves,$1
,$2
, ..., $10, $11, etc - Si se llama al argumento $0 estamos obteniendo el nombre del archivo
- Si queremos todos los argumentos lo hacemos mediante
$*
- Si lo que queremos es el número de argumentos que tenemos lo obtenemos mediante
$#
- Si queremos saner la salida del último comando lo podemos saber mediante
$?
- Si queremos saber el
PID
del script, lo podemos saber mediante$$
- Podemos remplazar el valor de una cadena de un argumento mediante
`${<indice de argumento>/cadena que se quiere sustituir/cadena nueva}`
, es decir, si tenemos${1/hola/hello}
sustituirá la palabrahola
por la palabrahello
en el argumento 1 - Sin embargo, si usamos
${<indice de argumento>/#cadena que se quiere sustituir/cadena nueva}
, solo sustituirá la cadena en el argumento si este argumento empieza por dicha cadena
%%writefile scripts_bash/04_argumentos.sh#!/bin/bash# Pasos de argumentos simplesecho "Primer argumento: $1"echo "Segundo argumento: $2"echo "Tercer argumento: $3"# Accediendo a todos los argumentosecho "Todos los argumentos: $*"# Accediendo al número de argumentosecho "Número de argumentos: $#"# Accediendo al nombre del scriptecho "Nombre del script: $0"# Accediendo al código de salida del último comando ejecutadoecho "Código de salida del último comando: $?"# Accediendo al PID del scriptecho "PID del script: $$"# Accediendo a los argumentos con índicesecho "Argumento 3: ${3}"echo "Argumento 2: ${2}"# Accediendo a los argumentos con índices y longitud máximaecho "Argumento 3 con longitud máxima de 2 caracteres: ${3:0:2}"echo "Argumento 2 con longitud máxima de 3 caracteres: ${2:0:3}"# Reemplazando argumentos con índices y longitud máximaecho "Reemplazando argumento 3: ${3/arg/ARG}"echo "Reemplazando argumento 2: $ {2/arg/ARG}"# Accediendo a los argumentos con índices y patrones de reemplazoecho "Reemplazando patrón en argumento 3: ${3/#tercer/TERCER}"echo "Reemplazando patrón en argumento 2: ${2/#arg/ARG}"
Overwriting scripts_bash/04_argumentos.sh
!arg1="primer argumento" && arg2="segundo argumento" && arg3="tercer argumento" && chmod +x scripts_bash/04_argumentos.sh && ./scripts_bash/04_argumentos.sh "$arg1" "$arg2" "$arg3"
Primer argumento: primer argumentoSegundo argumento: segundo argumentoTercer argumento: tercer argumentoTodos los argumentos: primer argumento segundo argumento tercer argumentoNúmero de argumentos: 3Nombre del script: ./scripts_bash/04_argumentos.shCódigo de salida del último comando: 0PID del script: 11644Argumento 3: tercer argumentoArgumento 2: segundo argumentoArgumento 3 con longitud máxima de 2 caracteres: teArgumento 2 con longitud máxima de 3 caracteres: segReemplazando argumento 3: tercer ARGumentoReemplazando argumento 2: segundo ARGumentoReemplazando patrón en argumento 3: tercer argumentoReemplazando patrón en argumento 2: segundo argumento
Ejecutar comandos y guardarlos en una variable
Tenemos dos maneras de ejecutar un comando y guardar su salida en una variable
- Mediante variable=
command
- Mediante
variable=$(command)
%%writefile scripts_bash/05_variables_comandos.sh#!/bin/bashpath=$(pwd)infokernel=`uname -a`echo "El directorio actual es: $path"echo "La información del kernel es: $infokernel"
Overwriting scripts_bash/05_variables_comandos.sh
!chmod +x scripts_bash/05_variables_comandos.sh && ./scripts_bash/05_variables_comandos.sh
El directorio actual es: /home/wallabot/Documentos/web/portafolio/postsLa información del kernel es: Linux wallabot 5.15.0-57-generic #63~20.04.1-Ubuntu SMP Wed Nov 30 13:40:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Debugging
Hay dos maneras de poder depurar en bash scripting
- Usando
-v
: Ejecución detallada de un script linea por línea - Usando
-x
: Despliegue de información del script
!bash -v scripts_bash/05_variables_comandos.sh
#!/bin/bashpath=$(pwd)infokernel=`uname -a`echo "El directorio actual es: $path"El directorio actual es: /home/wallabot/Documentos/web/portafolio/postsecho "La información del kernel es: $infokernel"La información del kernel es: Linux wallabot 5.15.0-57-generic #63~20.04.1-Ubuntu SMP Wed Nov 30 13:40:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
!bash -x scripts_bash/05_variables_comandos.sh
++ pwd+ path=/home/wallabot/Documentos/web/portafolio/posts++ uname -a+ infokernel='Linux wallabot 5.15.0-57-generic #63~20.04.1-Ubuntu SMP Wed Nov 30 13:40:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux'+ echo 'El directorio actual es: /home/wallabot/Documentos/web/portafolio/posts'El directorio actual es: /home/wallabot/Documentos/web/portafolio/posts+ echo 'La información del kernel es: Linux wallabot 5.15.0-57-generic #63~20.04.1-Ubuntu SMP Wed Nov 30 13:40:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux'La información del kernel es: Linux wallabot 5.15.0-57-generic #63~20.04.1-Ubuntu SMP Wed Nov 30 13:40:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Obtener información del usuario
Obtener información mediante los comandos echo
y read
Tenemos dos maneras de obtener información del usuario
- Mediante el comando
echo -n
. Con el flag-n
indicamos que no queremos que se imprima un salto de línea al final delecho
. Por ejemplo,echo -n "Introduce dato: "
, con este comando le pedimos un dato y el cursor se quedará en la misma linea, no habrá un salto - Mediante el comando
read
. Con este comando el programa se quedará esperando aq eu el usuario introduzca datos terminando con un salto de linea. Lo que haya introducido lo guardará en la variableREPLY
. Si se quiere que la variable donde se guarda el dato introducido por el usuario tenga otro ombre se debe introducirread [variable]
, por ejemplo el comandoread miVariable
, guardará el dato del usuario en la variablemiVariable
- Mediante el comando
$REPLY
o$[variable]
accedemos al dato introducido por el usuario.
%%writefile scripts_bash/06_leer_informacion.sh#!/bin/bashoption=0backupName=""echo "Programa de utilidades"echo -n "Ingresar una opción: "readoption=$REPLYecho ""echo -n "Ingresar un nombre: "read backupNameecho ""echo "Opción: $option, backupName: $backupName"
Overwriting scripts_bash/06_leer_informacion.sh
Como en un jupyter notebook no puedo meter los datos según me los va pidiendo, se los meto antes en un pipe |
!chmod +x scripts_bash/06_leer_informacion.sh && echo "1 nombreprueba" | ./scripts_bash/06_leer_informacion.sh
Programa de utilidadesIngresar una opción:Ingresar un nombre:Opción: 1, backupName: nombreprueba
Obtener información solo mediante el comando read
Otra forma de obtener información es usar solo el comando read
, la sintaxsis sería
read -p "Mensaje de prompt:" [variable]
El flag -p
indica que el mensaje Mensaje de prompt:
se mostrará antes de esperar a que el usuario introduzca el dato. Si no se especifica nombre de variable, el dato se guardará en la variable REPLY
%%writefile scripts_bash/06_leer_informacion.sh#!/bin/bashoption=0backupName=""echo "Programa de utilidades"echo -n "Ingresar una opción: "readoption1=$REPLYecho ""echo -n "Ingresar un nombre: "read backupNameecho ""read -p "Ingresar otra opción: " option2echo ""echo "Opción: $option1-$option2, backupName: $backupName"
Overwriting scripts_bash/06_leer_informacion.sh
!chmod +x scripts_bash/06_leer_informacion.sh && echo "1 nombreprueba 2" | ./scripts_bash/06_leer_informacion.sh
Programa de utilidadesIngresar una opción:Ingresar un nombre:Opción: 1-2, backupName: nombreprueba
Validar la información del usuario
Para validar la información del usuario lo mejor sería usar expresiones regulares, aquí dejo un post donde las explico
Además podemos especificar el número de caracteres que queremos que el usuario introduzca cuando usamos read
, para ello usamos el flag -n
, el cual, si no le sigue ningún número esperará hasta que el usuario introduzca un salto de linea, y si le sigue un número, esperará hasta que el usuario introduzca ese número de caracteres
%%writefile scripts_bash/07_validar_informacion.sh#!/bin/bashoption=0backupName=""echo "Programa de utilidades"echo -n "Ingresar una opción: "read -n1option1=$REPLYecho ""echo -n "Ingresar un nombre: "read -n4 backupNameecho ""read -p "Ingresar otra opción: " option2echo ""echo "Opción: $option1-$option2, backupName: $backupName"
Writing scripts_bash/07_validar_informacion.sh
!chmod +x scripts_bash/07_validar_informacion.sh && echo "1back2" | ./scripts_bash/07_validar_informacion.sh
Programa de utilidadesIngresar una opción:Ingresar un nombre:Opción: 1-2, backupName: back
Si queremos que introduzca un valor confidencial, como una clave, ponemos el flag -s
(security). De esta manera, cuando el usuario introduzca el dato, este no se imprimirá en la consola
%%writefile scripts_bash/07_validar_informacion.sh#!/bin/bashoption=0backupName=""echo "Programa de utilidades"echo -n "Ingresar una opción: "read -n1option1=$REPLYecho ""echo -n "Ingresar un nombre: "read -n4 backupNameecho ""read -p "Ingresar otra opción: " option2echo ""read -s -p "Password: " passwordecho ""echo "Opción: $option1-$option2, backupName: $backupName, password: $password"
Overwriting scripts_bash/07_validar_informacion.sh
!chmod +x scripts_bash/07_validar_informacion.sh && echo "1back2 1234" | ./scripts_bash/07_validar_informacion.sh
Programa de utilidadesIngresar una opción:Ingresar un nombre:Opción: 1-2, backupName: back, password: 1234
If else
La manera de escribir condicionales if
-else
es:
if [[condicion]]; then
statement
elif [[condicion]]; then
statement
else
statement
fi
Es importante recalcar que las condiciones tienen que estar entre dos corchetes [[]]
%%writefile scripts_bash/08_if_else.sh#!/bin/bashif [[ 1 > 2 ]]; thenecho "Verdadero"elif [[ 1 > 3 ]]; thenecho "Verdadero"elseecho "Falso"fi
Overwriting scripts_bash/08_if_else.sh
!chmod +x scripts_bash/08_if_else.sh && ./scripts_bash/08_if_else.sh
Falso
Veamos cómo se crean if
s anidados
%%writefile scripts_bash/08_if_else.sh#!/bin/bashif [[ 1 > 2 ]]; thenecho "Verdadero"elif [[ 1 > 3 ]]; thenecho "Verdadero"elseif [[ 1 > 4 ]]; thenecho "Verdadero pero falso"elseecho "Totalmente falso"fifi
Overwriting scripts_bash/08_if_else.sh
!chmod +x scripts_bash/08_if_else.sh && ./scripts_bash/08_if_else.sh
Totalmente falso
Expresiones condicionales
Ya hemos visto como crear if
s, pero es necesario explicar cómo crear las expresiones condicionales
Si vamos a realizar comparaciones entre cadenas o strings
operacion | comando | ejemplo |
---|---|---|
mayor que | > | [[ cadena1 > cadena2 ]] |
menor que | < | [[ cadena1 < cadena2 ]] |
igual que | == | [[ cadena1 == cadena2 ]] |
igual que | = | [[ cadena1 = cadena2 ]] |
cadena vacía | -z | [[ -z cadena ]] |
cadena no vacía | -n | [[ -n cadena ]] |
cadena no vacía | [[ cadena ]] |
Si lo que vamos a hacer es realizar comparaciones entre números
operacion | comando | ejemplo |
---|---|---|
mayor que | -gt | [[ numero1 -gt numero2 ]] |
mayor o igual que | -ge | [[ numero1 -ge numero2 ]] |
menor que | -lt | [[ numero1 -lt numero2 ]] |
menor o igual que | -le | [[ numero1 -le numero2 ]] |
igual que | -eq | [[ numero1 -eq numero2 ]] |
distinto que | -ne | [[ numero1 -ne numero2 ]] |
Si queremos comprobar archivos o directorios
operacion | comando | ejemplo |
---|---|---|
es un directorio? | -d | [[ -d <dir> ]] |
es un archivo? | -f | [[ -f <file> ]] |
existe? | -e | [[ -e <file> ]] o [[ -e <dir> ]] |
es legible? | -r | [[ -r <file> ]] |
es escribible? | -w | [[ -w <file> ]] |
es ejecutable? | -x | [[ -x <file> ]] |
es un link? | -L | [[ -L <file> ]] |
es tiene contenido? | -s | [[ -s <file> ]] |
es propiedad del usuario? | -O | [[ -O <file> ]] |
es propiedad del grupo? | -G | [[ -G <file> ]] |
fue modificado? | -N | [[ -N <file> ]] |
file1 es más nuevo que file2? | -nt | [[ <file1> -nt <file2> ]] |
file1 es más viejo que file2? | -ot | [[ <file1> -ot <file2> ]] |
file1 es el mismo archivo que file2? | -ef | [[ <file1> -ef <file2> ]] |
file1 es el mismo archivo que file2? | -ef | [[ <file1> -ef <file2> ]] |
Si queremos comparar condiciones conjuntas con and
, or
y not
operacion | comando | ejemplo | ||||
---|---|---|---|---|---|---|
and | && | [[ <condicion1> && <condicion2> ]] | ||||
or | ` | ` | `[[ |
Si queremos negar condiciones
operacion | comando | ejemplo |
---|---|---|
not | ! | [[ ! <condicion> ]] |
%%writefile scripts_bash/09_condicionales.sh#!/bin/bashecho "Comparando strings"string1="hola"string2="hola"string3="chao"string4=""if [[ $string1 > $string3 ]]; thenecho "$string1 es mayor que $string3"fiif [[ $string3 < $string1 ]]; thenecho "$string3 es menor que $string1"fiif [[ $string1 == $string2 ]]; thenecho "$string1 es igual que $string2"fiif [[ $string1 != $string3 ]]; thenecho "$string1 es diferente que $string3"fiif [[ -z $string4 ]]; thenecho "$string4 es una cadena vacía"fiif [[ -n $string3 ]]; thenecho "$string3 es una cadena no vacía"fiif [[ $string3 ]]; thenecho "$string3 es una cadena no vacía"fiecho -e "\nComparando números"number1=10number2=10number3=20if [[ $number3 -gt $number1 ]]; thenecho "$number3 es mayor que $number1"fiif [[ $number3 -ge $number2 ]]; thenecho "$number3 es mayor o igual que $number2"fiif [[ $number1 -lt $number3 ]]; thenecho "$number1 es menor que $number3"fiif [[ $number1 -le $number2 ]]; thenecho "$number1 es menor o igual que $number2"fiif [[ $number1 -eq $number2 ]]; thenecho "$number1 es igual que $number2"fiif [[ $number1 -ne $number3 ]]; thenecho "$number1 es diferente que $number3"fiecho -e "\nComparando archivos"file1="$PWD/2021-02-11-Introduccion-a-Python.ipynb"file2="$PWD/scripts_bash"file3="$PWD/mi_paquete_de_python"if [[ -d $file2 ]]; thenecho "$file2 es un directorio"fiif [[ -f $file1 ]]; thenecho "$file1 es un archivo"fiif [[ -e $file1 ]]; thenecho "$file1 existe"fiif [[ -r $file1 ]]; thenecho "$file1 es legible"fiif [[ -w $file1 ]]; thenecho "$file1 es escribible"fiif [[ -x $file1 ]]; thenecho "$file1 es ejecutable"fiif [[ -L $file1 ]]; thenecho "$file1 es un link"fiif [[ -s $file1 ]]; thenecho "$file1 tiene contenido"fiif [[ -O $file1 ]]; thenecho "$file1 es propiedad del usuario"fiif [[ -G $file1 ]]; thenecho "$file1 es propiedad del grupo"fiif [[ -N $file1 ]]; thenecho "$file1 fue modificado"fiif [[ $file1 -nt $file2 ]]; thenecho "$file1 es más nuevo que $file2"fiif [[ $file1 -ot $file2 ]]; thenecho "$file1 es más viejo que $file2"fiif [[ $file1 -ef $file1 ]]; thenecho "$file1 es el mismo archivo que $file2"fiecho -e "\nComparando expresiones con AND"if [[ 2 > 1 && 3 > 1 ]]; thenecho "2 > 1 y 3 > 1"fiecho -e "\nComparando expresiones con OR"if [[ 2 > 1 || 1 > 2 ]]; thenecho "2 > 1 o 1 > 2"fiecho -e "\nComparando expresiones con NOT"if [[ ! 1 > 2 ]]; thenecho "1 > 2 no es cierto"fi
Overwriting scripts_bash/09_condicionales.sh
!chmod +x scripts_bash/09_condicionales.sh && ./scripts_bash/09_condicionales.sh
Comparando stringshola es mayor que chaochao es menor que holahola es igual que holahola es diferente que chaoes una cadena vacíachao es una cadena no vacíachao es una cadena no vacíaComparando números20 es mayor que 1020 es mayor o igual que 1010 es menor que 2010 es menor o igual que 1010 es igual que 1010 es diferente que 20Comparando archivos/home/wallabot/Documentos/web/portafolio/posts/scripts_bash es un directorio/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es un archivo/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb existe/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es legible/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es escribible/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb tiene contenido/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es propiedad del usuario/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es propiedad del grupo/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es más viejo que /home/wallabot/Documentos/web/portafolio/posts/scripts_bash/home/wallabot/Documentos/web/portafolio/posts/2021-02-11-Introduccion-a-Python.ipynb es el mismo archivo que /home/wallabot/Documentos/web/portafolio/posts/scripts_bashComparando expresiones con AND2 > 1 y 3 > 1Comparando expresiones con OR2 > 1 o 1 > 2Comparando expresiones con NOT1 > 2 no es cierto
Sentencia case
A continuación vamos a ver cómo se escribe el típico switch-case
, pero en este caso solo se usa case
case $variable in
<valor1>) <sentencia1>;;
<valor2>) <sentencia2>;;
<valor3>) <sentencia3>;;
...
*) <sentencia que no cumple ninguna de las anteriores>
esac
%%writefile scripts_bash/10_case.sh#!/bin/bashvariable="amarillo"case $variable in"rojo") echo "Color rojo";;"verde") echo "Color verde";;"azul") echo "Color azul";;*) echo "Color desconocido";;esac
Writing scripts_bash/10_case.sh
!chmod +x scripts_bash/10_case.sh && ./scripts_bash/10_case.sh
Color desconocido
Arrays
Vamos a ver cómo se comportan los arrays en bash scripting
%%writefile scripts_bash/11_arrays.sh#!/bin/basharrayNumeros=(1 2 3 4 5)arrayStrings=("hola" "chao" "adios")arrayMixto=(1 "hola" 2 "chao" 3 "adios")arrayVacio=()arrayRango=({A..Z})echo "Arrays"echo "Array de números: ${arrayNumeros[*]}"echo "Array de strings: ${arrayStrings[*]}"echo "Array mixto: ${arrayMixto[*]}"echo "Array vacío: ${arrayVacio[*]}"echo "Array de rango: ${arrayRango[*]}"echo -e "\nAccediendo a elementos"echo "Primer elemento del array de números: ${arrayNumeros[0]}"echo "Segundo elemento del array de strings: ${arrayStrings[1]}"echo "Último elemento del array de números: ${arrayNumeros[-1]}"echo "Penúltimo elemento del array de strings: ${arrayStrings[-2]}"echo -e "\nLongitud de arrays"echo "Longitud del array de números: ${#arrayNumeros[*]}"echo "Longitud del array de strings: ${#arrayStrings[*]}"echo "Longitud del array mixto: ${#arrayMixto[*]}"echo "Longitud del array vacío: ${#arrayVacio[*]}"echo "Longitud del array de rango: ${#arrayRango[*]}"echo -e "\nAñadiendo y eliminando elementos"arrayNumeros[5]=6echo "Añadiendo elemento al array de números: ${arrayNumeros[*]}"unset arrayStrings[1]echo "Eliminando elemento del array de strings: ${arrayStrings[*]}"
Overwriting scripts_bash/11_arrays.sh
!chmod +x scripts_bash/11_arrays.sh && ./scripts_bash/11_arrays.sh
ArraysArray de números: 1 2 3 4 5Array de strings: hola chao adiosArray mixto: 1 hola 2 chao 3 adiosArray vacío:Array de rango: A B C D E F G H I J K L M N O P Q R S T U V W X Y ZAccediendo a elementosPrimer elemento del array de números: 1Segundo elemento del array de strings: chaoÚltimo elemento del array de números: 5Penúltimo elemento del array de strings: chaoLongitud de arraysLongitud del array de números: 5Longitud del array de strings: 3Longitud del array mixto: 6Longitud del array vacío: 0Longitud del array de rango: 26Añadiendo y eliminando elementosAñadiendo elemento al array de números: 1 2 3 4 5 6Eliminando elemento del array de strings: hola adios
Bucle for
Para utilizar el bucle for
hay que usar la siguiente sintaxis
for <variable> in <array>
do
sentencia
done
Vamos a ver un ejemplo
%%writefile scripts_bash/12_for.sh#!/bin/basharrayNumeros=(1 2 3 4 5)arrayStrings=("hola" "chao" "adios")echo "Iterar a través de un array de numeros"for numero in ${arrayNumeros[*]}doecho "Número: $numero"doneecho -e "\nIterar a través de un array de strings"for string in ${arrayStrings[*]}doecho "String: $string"doneecho -e "\nIterar a través de un array no declarado"for string in "Manolo" "Juan" "Pedro"doecho "String: $string"doneecho -e "\nIterar a través de un rango"for i in {1..10}doecho "Número: $i"doneecho -e "\nIterar a través de un rango de manera clásica"for (( i=1; i<=10; i++ ))doecho "Número: $i"doneecho -e "\nIterar a través de un comando"for file in $(ls)doecho "Archivo: $file"doneecho -e "\nIterar a través de un directorio"for file in *doecho "Archivo: $file"done
Overwriting scripts_bash/12_for.sh
!chmod +x scripts_bash/12_for.sh && ./scripts_bash/12_for.sh
Iterar a través de un array de numerosNúmero: 1Número: 2Número: 3Número: 4Número: 5Iterar a través de un array de stringsString: holaString: chaoString: adiosIterar a través de un array no declaradoString: ManoloString: JuanString: PedroIterar a través de un rangoNúmero: 1Número: 2Número: 3Número: 4Número: 5Número: 6Número: 7Número: 8Número: 9Número: 10Iterar a través de un rango de manera clásicaNúmero: 1Número: 2Número: 3Número: 4Número: 5Número: 6Número: 7Número: 8Número: 9Número: 10Iterar a través de un comandoArchivo: 2021-02-11-Introduccion-a-Python.ipynbArchivo: 2021-04-23-Calculo-matricial-con-Numpy.ipynbArchivo: 2021-06-15-Manejo-de-datos-con-Pandas.ipynbArchivo: 2022-09-12-Introduccion-a-la-terminal.ipynbArchivo: 2023-01-22-Docker.ipynbArchivo: 2023-XX-XX-Bash-scripting.ipynbArchivo: california_housing_train.csvArchivo: command-line-cheat-sheet.pdfArchivo: CSS.ipynbArchivo: ExpresionesArchivo: regulares.ipynbArchivo: html_filesArchivo: html.ipynbArchivo: introduccion_pythonArchivo: mi_paquete_de_pythonArchivo: movies.csvArchivo: movies.datArchivo: notebooks_translatedArchivo: __pycache__Archivo: scripts_bashArchivo: ssh.ipynbArchivo: test.ipynbIterar a través de un directorioArchivo: 2021-02-11-Introduccion-a-Python.ipynbArchivo: 2021-04-23-Calculo-matricial-con-Numpy.ipynbArchivo: 2021-06-15-Manejo-de-datos-con-Pandas.ipynbArchivo: 2022-09-12-Introduccion-a-la-terminal.ipynbArchivo: 2023-01-22-Docker.ipynbArchivo: 2023-XX-XX-Bash-scripting.ipynbArchivo: california_housing_train.csvArchivo: command-line-cheat-sheet.pdfArchivo: CSS.ipynbArchivo: Expresiones regulares.ipynbArchivo: html_filesArchivo: html.ipynbArchivo: introduccion_pythonArchivo: mi_paquete_de_pythonArchivo: movies.csvArchivo: movies.datArchivo: notebooks_translatedArchivo: __pycache__Archivo: scripts_bashArchivo: ssh.ipynbArchivo: test.ipynb
Bucle while
Para utilizar el bucle while
hay que usar la siguiente sintaxis
while <condicion>
do
sentencia
done
Vamos a ver un ejemplo
%%writefile scripts_bash/13_while.sh#!/bin/bashnumero=1while [ $numero -ne 5 ]doecho "Número: $numero"numero=$(( numero + 1 ))done
Overwriting scripts_bash/13_while.sh
!chmod +x scripts_bash/13_while.sh && ./scripts_bash/13_while.sh
Número: 1Número: 2Número: 3Número: 4
Control de flujo con break
y continue
Podemos controlar el el flujo de un bucle mediante las palabras break
y continue
, veamos un ejemplo
%%writefile scripts_bash/14_control_de_flujo.sh#!/bin/bashnumero=1while [ $numero -ne 10 ]doif [ $numero -eq 5 ]; thennumero=$(( numero + 1 ))echo "Saltando el número 5"continueelif[ $numero -eq 8 ]; thenecho "Terminando el bucle"breakfiecho "Número: $numero"numero=$(( numero + 1 ))done
Overwriting scripts_bash/14_control_de_flujo.sh
!chmod +x scripts_bash/14_control_de_flujo.sh && ./scripts_bash/14_control_de_flujo.sh
Número: 1Número: 2Número: 3Número: 4Saltando el número 5Número: 6Número: 7Terminando el bucle
Funciones
La sintaxis para escribir funciones es
<nombre de funcion> (){
sentencias
}
Veamos un ejemplo
%%writefile scripts_bash/15_funciones.sh#!/bin/bashfuncion () {echo "Soy una función"}funcoionConParametros () {echo "Soy una función con parámetros"echo "Parámetro 1: $1"echo "Parámetro 2: $2"}funcionfuncoionConParametros "Hola" "Adiós"
Writing scripts_bash/15_funciones.sh
!chmod +x scripts_bash/15_funciones.sh && ./scripts_bash/15_funciones.sh
Soy una funciónSoy una función con parámetrosParámetro 1: HolaParámetro 2: Adiós