Bash scripting

Bash scripting Bash scripting

Bash scriptinglink image 0

Carpeta con scriptslink image 1

Para realizar este post vamos a crear una carpeta donde vamos a guardar todos los scripts

	
!mkdir scripts_bash
Copy

Primer scriptlink image 2

Especificación del binario de ejecuciónlink image 3

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 bashlink image 4

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 echolink image 5

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 varias
lineas
'
echo "Hola mundo"
Copy
	
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
Copy
	
Hola mundo

Declaración de variableslink image 6

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/bash
opcion=1
nombre="Juan"
echo "Opcion: $opcion"
echo "Nombre: $nombre"
Copy
	
Writing scripts_bash/02_variables.sh
	
!chmod +x scripts_bash/02_variables.sh && ./scripts_bash/02_variables.sh
Copy
	
Opcion: 1
Nombre: Juan

Alcande de las variableslink image 7

Las variables creadas solo son accesibles desde el script, es decir, su alcance es dentro del script

Exportación de variableslink image 8

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/bash
opcion=1
nombre="Juan"
echo "Opcion: $opcion"
echo "Nombre: $nombre"
# Exportar variable nombre
echo "export nombre=$nombre"
export nombre
# Ejecutar script de importacion
echo ""
echo "Ejecutando script de importacion"
./scripts_bash/02_variables_importacion.sh
Copy
	
Overwriting scripts_bash/02_variables.sh
	
%%writefile scripts_bash/02_variables_importacion.sh
#!/bin/bash
echo "Nombre importado: $nombre"
Copy
	
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
Copy
	
Opcion: 1
Nombre: Juan
export nombre=Juan
Ejecutando script de importacion
Nombre 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
Copy
	
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 operadoreslink image 9

A continuación mostramos todos los posibles operadores

	
%%writefile scripts_bash/03_operadores.sh
#!/bin/bash
# Asignación de variables
x=10
y=20
echo "x = $x"
echo "y = $y"
# Operadores aritméticos
echo ""
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ón
echo ""
echo "Operadores de comparación"
if [ "$x" -eq "$y" ]; then
echo "x es igual a y"
else
echo "x no es igual a y"
fi
if [ "$x" -ne "$y" ]; then
echo "x no es igual a y"
else
echo "x es igual a y"
fi
if [ "$x" -lt "$y" ]; then
echo "x es menor que y"
else
echo "x no es menor que y"
fi
if [ "$x" -gt "$y" ]; then
echo "x es mayor que y"
else
echo "x no es mayor que y"
fi
# Operadores de cadena
echo ""
echo "Operadores de cadena"
if [ "$a" = "$b" ]; then
echo "a es igual a b"
else
echo "a no es igual a b"
fi
if [ "$a" != "$b" ]; then
echo "a no es igual a b"
else
echo "a es igual a b"
fi
if [ -z "$a" ]; then
echo "a es una cadena vacía"
else
echo "a no es una cadena vacía"
fi
if [ -n "$a" ]; then
echo "a no es una cadena vacía"
else
echo "a es una cadena vacía"
fi
# Operadores de archivo
echo ""
echo "Operadores de archivo"
if [ -e "/path/to/file" ]; then
echo "El archivo existe"
else
echo "El archivo no existe"
fi
if [ -f "/path/to/file" ]; then
echo "Es un archivo regular"
else
echo "No es un archivo regular"
fi
if [ -d "/path/to/dir" ]; then
echo "Es un directorio"
else
echo "No es un directorio"
fi
Copy
	
Overwriting scripts_bash/03_operadores.sh
	
!chmod +x scripts_bash/03_operadores.sh && ./scripts_bash/03_operadores.sh
Copy
	
x = 10
y = 20
Operadores aritméticos
x + y = 30
x - y = -10
x * y = 200
x / y = 0
x % y = 10
Operadores de comparación
x no es igual a y
x no es igual a y
x es menor que y
x no es mayor que y
Operadores de cadena
a es igual a b
a es igual a b
a es una cadena vacía
a es una cadena vacía
Operadores de archivo
El archivo no existe
No es un archivo regular
No es un directorio

Paso de argumentoslink image 10

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 palabra hola por la palabra hello 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 simples
echo "Primer argumento: $1"
echo "Segundo argumento: $2"
echo "Tercer argumento: $3"
# Accediendo a todos los argumentos
echo "Todos los argumentos: $*"
# Accediendo al número de argumentos
echo "Número de argumentos: $#"
# Accediendo al nombre del script
echo "Nombre del script: $0"
# Accediendo al código de salida del último comando ejecutado
echo "Código de salida del último comando: $?"
# Accediendo al PID del script
echo "PID del script: $$"
# Accediendo a los argumentos con índices
echo "Argumento 3: ${3}"
echo "Argumento 2: ${2}"
# Accediendo a los argumentos con índices y longitud máxima
echo "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áxima
echo "Reemplazando argumento 3: ${3/arg/ARG}"
echo "Reemplazando argumento 2: $ {2/arg/ARG}"
# Accediendo a los argumentos con índices y patrones de reemplazo
echo "Reemplazando patrón en argumento 3: ${3/#tercer/TERCER}"
echo "Reemplazando patrón en argumento 2: ${2/#arg/ARG}"
Copy
	
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"
Copy
	
Primer argumento: primer argumento
Segundo argumento: segundo argumento
Tercer argumento: tercer argumento
Todos los argumentos: primer argumento segundo argumento tercer argumento
Número de argumentos: 3
Nombre del script: ./scripts_bash/04_argumentos.sh
Código de salida del último comando: 0
PID del script: 11644
Argumento 3: tercer argumento
Argumento 2: segundo argumento
Argumento 3 con longitud máxima de 2 caracteres: te
Argumento 2 con longitud máxima de 3 caracteres: seg
Reemplazando argumento 3: tercer ARGumento
Reemplazando argumento 2: segundo ARGumento
Reemplazando patrón en argumento 3: tercer argumento
Reemplazando patrón en argumento 2: segundo argumento

Ejecutar comandos y guardarlos en una variablelink image 11

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/bash
path=$(pwd)
infokernel=`uname -a`
echo "El directorio actual es: $path"
echo "La información del kernel es: $infokernel"
Copy
	
Overwriting scripts_bash/05_variables_comandos.sh
	
!chmod +x scripts_bash/05_variables_comandos.sh && ./scripts_bash/05_variables_comandos.sh
Copy
	
El directorio actual es: /home/wallabot/Documentos/web/portafolio/posts
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

Debugginglink image 12

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
Copy
	
#!/bin/bash
path=$(pwd)
infokernel=`uname -a`
echo "El directorio actual es: $path"
El directorio actual es: /home/wallabot/Documentos/web/portafolio/posts
echo "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
Copy
	
++ 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 usuariolink image 13

Obtener información mediante los comandos echo y readlink image 14

Tenemos dos maneras de obtener información del usuario

  1. Mediante el comando echo -n. Con el flag -n indicamos que no queremos que se imprima un salto de línea al final del echo. 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
  2. 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 variable REPLY. Si se quiere que la variable donde se guarda el dato introducido por el usuario tenga otro ombre se debe introducir read [variable], por ejemplo el comando read miVariable, guardará el dato del usuario en la variable miVariable
  3. Mediante el comando $REPLY o $[variable] accedemos al dato introducido por el usuario.
	
%%writefile scripts_bash/06_leer_informacion.sh
#!/bin/bash
option=0
backupName=""
echo "Programa de utilidades"
echo -n "Ingresar una opción: "
read
option=$REPLY
echo ""
echo -n "Ingresar un nombre: "
read backupName
echo ""
echo "Opción: $option, backupName: $backupName"
Copy
	
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
Copy
	
Programa de utilidades
Ingresar una opción:
Ingresar un nombre:
Opción: 1, backupName: nombreprueba

Obtener información solo mediante el comando readlink image 15

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/bash
option=0
backupName=""
echo "Programa de utilidades"
echo -n "Ingresar una opción: "
read
option1=$REPLY
echo ""
echo -n "Ingresar un nombre: "
read backupName
echo ""
read -p "Ingresar otra opción: " option2
echo ""
echo "Opción: $option1-$option2, backupName: $backupName"
Copy
	
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
Copy
	
Programa de utilidades
Ingresar una opción:
Ingresar un nombre:
Opción: 1-2, backupName: nombreprueba

Validar la información del usuariolink image 16

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/bash
option=0
backupName=""
echo "Programa de utilidades"
echo -n "Ingresar una opción: "
read -n1
option1=$REPLY
echo ""
echo -n "Ingresar un nombre: "
read -n4 backupName
echo ""
read -p "Ingresar otra opción: " option2
echo ""
echo "Opción: $option1-$option2, backupName: $backupName"
Copy
	
Writing scripts_bash/07_validar_informacion.sh
	
!chmod +x scripts_bash/07_validar_informacion.sh && echo "1back2" | ./scripts_bash/07_validar_informacion.sh
Copy
	
Programa de utilidades
Ingresar 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/bash
option=0
backupName=""
echo "Programa de utilidades"
echo -n "Ingresar una opción: "
read -n1
option1=$REPLY
echo ""
echo -n "Ingresar un nombre: "
read -n4 backupName
echo ""
read -p "Ingresar otra opción: " option2
echo ""
read -s -p "Password: " password
echo ""
echo "Opción: $option1-$option2, backupName: $backupName, password: $password"
Copy
	
Overwriting scripts_bash/07_validar_informacion.sh
	
!chmod +x scripts_bash/07_validar_informacion.sh && echo "1back2 1234" | ./scripts_bash/07_validar_informacion.sh
Copy
	
Programa de utilidades
Ingresar una opción:
Ingresar un nombre:
Opción: 1-2, backupName: back, password: 1234

If elselink image 17

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/bash
if [[ 1 > 2 ]]; then
echo "Verdadero"
elif [[ 1 > 3 ]]; then
echo "Verdadero"
else
echo "Falso"
fi
Copy
	
Overwriting scripts_bash/08_if_else.sh
	
!chmod +x scripts_bash/08_if_else.sh && ./scripts_bash/08_if_else.sh
Copy
	
Falso

Veamos cómo se crean ifs anidados

	
%%writefile scripts_bash/08_if_else.sh
#!/bin/bash
if [[ 1 > 2 ]]; then
echo "Verdadero"
elif [[ 1 > 3 ]]; then
echo "Verdadero"
else
if [[ 1 > 4 ]]; then
echo "Verdadero pero falso"
else
echo "Totalmente falso"
fi
fi
Copy
	
Overwriting scripts_bash/08_if_else.sh
	
!chmod +x scripts_bash/08_if_else.sh && ./scripts_bash/08_if_else.sh
Copy
	
Totalmente falso

Expresiones condicionaleslink image 18

Ya hemos visto como crear ifs, 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/bash
echo "Comparando strings"
string1="hola"
string2="hola"
string3="chao"
string4=""
if [[ $string1 > $string3 ]]; then
echo "$string1 es mayor que $string3"
fi
if [[ $string3 < $string1 ]]; then
echo "$string3 es menor que $string1"
fi
if [[ $string1 == $string2 ]]; then
echo "$string1 es igual que $string2"
fi
if [[ $string1 != $string3 ]]; then
echo "$string1 es diferente que $string3"
fi
if [[ -z $string4 ]]; then
echo "$string4 es una cadena vacía"
fi
if [[ -n $string3 ]]; then
echo "$string3 es una cadena no vacía"
fi
if [[ $string3 ]]; then
echo "$string3 es una cadena no vacía"
fi
echo -e "\nComparando números"
number1=10
number2=10
number3=20
if [[ $number3 -gt $number1 ]]; then
echo "$number3 es mayor que $number1"
fi
if [[ $number3 -ge $number2 ]]; then
echo "$number3 es mayor o igual que $number2"
fi
if [[ $number1 -lt $number3 ]]; then
echo "$number1 es menor que $number3"
fi
if [[ $number1 -le $number2 ]]; then
echo "$number1 es menor o igual que $number2"
fi
if [[ $number1 -eq $number2 ]]; then
echo "$number1 es igual que $number2"
fi
if [[ $number1 -ne $number3 ]]; then
echo "$number1 es diferente que $number3"
fi
echo -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 ]]; then
echo "$file2 es un directorio"
fi
if [[ -f $file1 ]]; then
echo "$file1 es un archivo"
fi
if [[ -e $file1 ]]; then
echo "$file1 existe"
fi
if [[ -r $file1 ]]; then
echo "$file1 es legible"
fi
if [[ -w $file1 ]]; then
echo "$file1 es escribible"
fi
if [[ -x $file1 ]]; then
echo "$file1 es ejecutable"
fi
if [[ -L $file1 ]]; then
echo "$file1 es un link"
fi
if [[ -s $file1 ]]; then
echo "$file1 tiene contenido"
fi
if [[ -O $file1 ]]; then
echo "$file1 es propiedad del usuario"
fi
if [[ -G $file1 ]]; then
echo "$file1 es propiedad del grupo"
fi
if [[ -N $file1 ]]; then
echo "$file1 fue modificado"
fi
if [[ $file1 -nt $file2 ]]; then
echo "$file1 es más nuevo que $file2"
fi
if [[ $file1 -ot $file2 ]]; then
echo "$file1 es más viejo que $file2"
fi
if [[ $file1 -ef $file1 ]]; then
echo "$file1 es el mismo archivo que $file2"
fi
echo -e "\nComparando expresiones con AND"
if [[ 2 > 1 && 3 > 1 ]]; then
echo "2 > 1 y 3 > 1"
fi
echo -e "\nComparando expresiones con OR"
if [[ 2 > 1 || 1 > 2 ]]; then
echo "2 > 1 o 1 > 2"
fi
echo -e "\nComparando expresiones con NOT"
if [[ ! 1 > 2 ]]; then
echo "1 > 2 no es cierto"
fi
Copy
	
Overwriting scripts_bash/09_condicionales.sh
	
!chmod +x scripts_bash/09_condicionales.sh && ./scripts_bash/09_condicionales.sh
Copy
	
Comparando strings
hola es mayor que chao
chao es menor que hola
hola es igual que hola
hola es diferente que chao
es una cadena vacía
chao es una cadena no vacía
chao es una cadena no vacía
Comparando números
20 es mayor que 10
20 es mayor o igual que 10
10 es menor que 20
10 es menor o igual que 10
10 es igual que 10
10 es diferente que 20
Comparando 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_bash
Comparando expresiones con AND
2 > 1 y 3 > 1
Comparando expresiones con OR
2 > 1 o 1 > 2
Comparando expresiones con NOT
1 > 2 no es cierto

Sentencia caselink image 19

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/bash
variable="amarillo"
case $variable in
"rojo") echo "Color rojo";;
"verde") echo "Color verde";;
"azul") echo "Color azul";;
*) echo "Color desconocido";;
esac
Copy
	
Writing scripts_bash/10_case.sh
	
!chmod +x scripts_bash/10_case.sh && ./scripts_bash/10_case.sh
Copy
	
Color desconocido

Arrayslink image 20

Vamos a ver cómo se comportan los arrays en bash scripting

	
%%writefile scripts_bash/11_arrays.sh
#!/bin/bash
arrayNumeros=(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]=6
echo "Añadiendo elemento al array de números: ${arrayNumeros[*]}"
unset arrayStrings[1]
echo "Eliminando elemento del array de strings: ${arrayStrings[*]}"
Copy
	
Overwriting scripts_bash/11_arrays.sh
	
!chmod +x scripts_bash/11_arrays.sh && ./scripts_bash/11_arrays.sh
Copy
	
Arrays
Array de números: 1 2 3 4 5
Array de strings: hola chao adios
Array mixto: 1 hola 2 chao 3 adios
Array 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 Z
Accediendo a elementos
Primer elemento del array de números: 1
Segundo elemento del array de strings: chao
Último elemento del array de números: 5
Penúltimo elemento del array de strings: chao
Longitud de arrays
Longitud del array de números: 5
Longitud del array de strings: 3
Longitud del array mixto: 6
Longitud del array vacío: 0
Longitud del array de rango: 26
Añadiendo y eliminando elementos
Añadiendo elemento al array de números: 1 2 3 4 5 6
Eliminando elemento del array de strings: hola adios

Bucle forlink image 21

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/bash
arrayNumeros=(1 2 3 4 5)
arrayStrings=("hola" "chao" "adios")
echo "Iterar a través de un array de numeros"
for numero in ${arrayNumeros[*]}
do
echo "Número: $numero"
done
echo -e "\nIterar a través de un array de strings"
for string in ${arrayStrings[*]}
do
echo "String: $string"
done
echo -e "\nIterar a través de un array no declarado"
for string in "Manolo" "Juan" "Pedro"
do
echo "String: $string"
done
echo -e "\nIterar a través de un rango"
for i in {1..10}
do
echo "Número: $i"
done
echo -e "\nIterar a través de un rango de manera clásica"
for (( i=1; i<=10; i++ ))
do
echo "Número: $i"
done
echo -e "\nIterar a través de un comando"
for file in $(ls)
do
echo "Archivo: $file"
done
echo -e "\nIterar a través de un directorio"
for file in *
do
echo "Archivo: $file"
done
Copy
	
Overwriting scripts_bash/12_for.sh
	
!chmod +x scripts_bash/12_for.sh && ./scripts_bash/12_for.sh
Copy
	
Iterar a través de un array de numeros
Número: 1
Número: 2
Número: 3
Número: 4
Número: 5
Iterar a través de un array de strings
String: hola
String: chao
String: adios
Iterar a través de un array no declarado
String: Manolo
String: Juan
String: Pedro
Iterar a través de un rango
Número: 1
Número: 2
Número: 3
Número: 4
Número: 5
Número: 6
Número: 7
Número: 8
Número: 9
Número: 10
Iterar a través de un rango de manera clásica
Número: 1
Número: 2
Número: 3
Número: 4
Número: 5
Número: 6
Número: 7
Número: 8
Número: 9
Número: 10
Iterar a través de un comando
Archivo: 2021-02-11-Introduccion-a-Python.ipynb
Archivo: 2021-04-23-Calculo-matricial-con-Numpy.ipynb
Archivo: 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
Archivo: 2022-09-12-Introduccion-a-la-terminal.ipynb
Archivo: 2023-01-22-Docker.ipynb
Archivo: 2023-XX-XX-Bash-scripting.ipynb
Archivo: california_housing_train.csv
Archivo: command-line-cheat-sheet.pdf
Archivo: CSS.ipynb
Archivo: Expresiones
Archivo: regulares.ipynb
Archivo: html_files
Archivo: html.ipynb
Archivo: introduccion_python
Archivo: mi_paquete_de_python
Archivo: movies.csv
Archivo: movies.dat
Archivo: notebooks_translated
Archivo: __pycache__
Archivo: scripts_bash
Archivo: ssh.ipynb
Archivo: test.ipynb
Iterar a través de un directorio
Archivo: 2021-02-11-Introduccion-a-Python.ipynb
Archivo: 2021-04-23-Calculo-matricial-con-Numpy.ipynb
Archivo: 2021-06-15-Manejo-de-datos-con-Pandas.ipynb
Archivo: 2022-09-12-Introduccion-a-la-terminal.ipynb
Archivo: 2023-01-22-Docker.ipynb
Archivo: 2023-XX-XX-Bash-scripting.ipynb
Archivo: california_housing_train.csv
Archivo: command-line-cheat-sheet.pdf
Archivo: CSS.ipynb
Archivo: Expresiones regulares.ipynb
Archivo: html_files
Archivo: html.ipynb
Archivo: introduccion_python
Archivo: mi_paquete_de_python
Archivo: movies.csv
Archivo: movies.dat
Archivo: notebooks_translated
Archivo: __pycache__
Archivo: scripts_bash
Archivo: ssh.ipynb
Archivo: test.ipynb

Bucle whilelink image 22

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/bash
numero=1
while [ $numero -ne 5 ]
do
echo "Número: $numero"
numero=$(( numero + 1 ))
done
Copy
	
Overwriting scripts_bash/13_while.sh
	
!chmod +x scripts_bash/13_while.sh && ./scripts_bash/13_while.sh
Copy
	
Número: 1
Número: 2
Número: 3
Número: 4

Control de flujo con break y continuelink image 23

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/bash
numero=1
while [ $numero -ne 10 ]
do
if [ $numero -eq 5 ]; then
numero=$(( numero + 1 ))
echo "Saltando el número 5"
continue
elif
[ $numero -eq 8 ]; then
echo "Terminando el bucle"
break
fi
echo "Número: $numero"
numero=$(( numero + 1 ))
done
Copy
	
Overwriting scripts_bash/14_control_de_flujo.sh
	
!chmod +x scripts_bash/14_control_de_flujo.sh && ./scripts_bash/14_control_de_flujo.sh
Copy
	
Número: 1
Número: 2
Número: 3
Número: 4
Saltando el número 5
Número: 6
Número: 7
Terminando el bucle

Funcioneslink image 24

La sintaxis para escribir funciones es

<nombre de funcion> (){
          sentencias
      }
      

Veamos un ejemplo

	
%%writefile scripts_bash/15_funciones.sh
#!/bin/bash
funcion () {
echo "Soy una función"
}
funcoionConParametros () {
echo "Soy una función con parámetros"
echo "Parámetro 1: $1"
echo "Parámetro 2: $2"
}
funcion
funcoionConParametros "Hola" "Adiós"
Copy
	
Writing scripts_bash/15_funciones.sh
	
!chmod +x scripts_bash/15_funciones.sh && ./scripts_bash/15_funciones.sh
Copy
	
Soy una función
Soy una función con parámetros
Parámetro 1: Hola
Parámetro 2: Adiós

Seguir leyendo

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

¿Alguna vez has hablado con un LLM y te ha respondido algo que suena como si hubiera estado bebiendo café de máquina durante toda la noche? 😂 ¡Eso es lo que llamamos una alucinación en el mundo de los LLMs! Pero no te preocupes, porque no es que tu modelo de lenguaje esté loco (aunque a veces puede parecerlo 🤪). La verdad es que los LLMs pueden ser un poco... creativos cuando se trata de generar texto. Pero gracias a DoLa, un método que utiliza capas de contraste para mejorar la factibilidad de los LLMs, podemos evitar que nuestros modelos de lenguaje se conviertan en escritores de ciencia ficción 😂. En este post, te explicaré cómo funciona DoLa y te mostraré un ejemplo de código para que puedas entender mejor cómo hacer que tus LLMs sean más fiables y menos propensos a inventar historias. ¡Vamos a salvar a nuestros LLMs de la locura y hacer que sean más útiles! 🚀

Últimos posts -->

¿Has visto estos proyectos?

Subtify

Subtify Subtify

Generador de subtítulos para videos en el idioma que desees. Además a cada persona le pone su subtítulo de un color

Ver todos los proyectos -->

¿Quieres aplicar la IA en tu proyecto? Contactame!

¿Quieres mejorar con estos tips?

Últimos tips -->

Usa esto en local

Los espacios de Hugging Face nos permite ejecutar modelos con demos muy sencillas, pero ¿qué pasa si la demo se rompe? O si el usuario la elimina? Por ello he creado contenedores docker con algunos espacios interesantes, para poder usarlos de manera local, pase lo que pase. De hecho, es posible que si pinchas en alún botón de ver proyecto te lleve a un espacio que no funciona.

Ver todos los contenedores -->

¿Quieres aplicar la IA en tu proyecto? Contactame!

¿Quieres entrenar tu modelo con estos datasets?

short-jokes-dataset

Dataset de chistes en inglés

opus100

Dataset con traducciones de inglés a español

netflix_titles

Dataset con películas y series de Netflix

Ver más datasets -->