# Tutorial Bash III


## ¡Hola, internauta! {#hola-internauta}

Hoy quiero traerte un tutorial de **Bash** más, ya que a eso vienes ¿no? a aprender, en este tutorial te daré un complemento muy importante para **Bash** y en general para el mundo del desarrollo, espero que hasta los momentos los anteriores post te hayan servido y que hayas practicado (al menos lo necesario) ya que para esto no se necesita ser un genio, solo practicar y practicar, ya sabes, debes de tener mucha curiosidad y amor por lo que haces.

> La curiosidad nomató al gato... solo lo llevó a hackear su arenero inteligente. 🐱💻
>
> {{< style "text-align: right;" >}}_Raksodiano_{{< /style >}}


## Funciones {#funciones}

Las funciones son bloques de código reutilizables, que nos permiten definirlas una sola vez y ejecutarlas las veces que sean necesarias dentro de nuestros scripts o sesión de shell. Estas funciones nos permiten estructurar mejor nuestros scripts, evitando así la repetición de código y facilitando el mantenimiento de los scripts.

En sus sintaxis básicas tenemos dos formas de definirlas, una con la palabra reservada `function` y la otra sin la palabra en donde solo definimos el nombre de la misma y finalizando con parentesis.

```bash
function nombre_funcion_sexy {
  # instrucciones sensuales
}

nombre_funcion_sexy() {
  # instrucciones sensuales
}
```

Como podemos ver, dentro de ellas tenemos una estructura muy simple donde definimos el bloque de código que vamos a utilizar dentro de las llaves "{" "}", dentro de las mismas podemos definir todo lo que ya hemos visto en los tutoriales anteriores y llamar a la función en cualquier parte del script que queramos o necesitemos.

Como ejemplo, podemos hacer esto;

```bash
#!/bin/bash

# Definimos la función
function mi_sexy_funcion_super_sensual {

  # Definimos una salida
  echo "Soy una función muy sexy"
}

# Llamado de la función
# Así es como se debe de llamar la función
mi_sexy_funcion_super_sensual
```

```bash
#!/bin/bash

soy_super_sensual() {
  echo "Función sensual"
}

soy_super_sensual
```

{{< admonition tip "Tip" false >}}
Trata de eliminar el llamado de la función dentro del script y ejecutalo, para que puedas ver que esas sexys y suculentas no se ejecutaran ni se moveran por tí.
{{< /admonition >}}


## Manejo de argumentos y entradas del usuario {#manejo-de-argumentos-y-entradas-del-usuario}

En **Bash** podemos hacer uso de argumentos y entradas, lo cual es escencial para que nuestros scripts sean interactivos y reutilizables, para ello vamos a explicar un poco mejor como se deben de trabajar con estas suculentas funcionalidades de los scripts;


### Argumentos {#argumentos}

Los argumentos nos permiten agregar opciones para poder darle dinamismo a los scripts, donde podríamos darle diversas opciones y caminos a seguir dependiendo de las diferentes opciones que nosotros escribamos.

```bash
#!/bin/bash

echo "Nombre del sexy script: $0"            # Este mostrará el nombre del script
echo "Primer sensual argumento: $1"          # Este mostrará el primer parametro que envies
echo "Segundo sensual argumento: $2"         # Este mostrará el segundo parametro
echo "Número de sensuales argumentos: $#"    # Este mostrará los argumentos enviados
```

Puedes hacer pruebas de esta forma (recuerda crear el script y darle el nombre de `sensual`);

```sh
./sensual.sh Soy sensual
```

{{< admonition tip "Tip" false >}}
Trata de ir cambiando los argumentos como números, agregando más sensuales argumentos y cosas por el estilo, no soy quien va a darte las respuestas.
{{< /admonition >}}


### Entrada del usuario {#entrada-del-usuario}

En las entradas del usuario, ya vimos como hacerlo con el comando `read`.

```bash
#!/bin/bash

echo -n "¿Cómo te llamas guapo? "
read nombre

echo "Hola, sexy $nombre"
```

{{< admonition tip "Tip" false >}}
¿Qué? ¿también quieres las respuestas de aquí? nel, vaya y busque en internet.
{{< /admonition >}}


## Depuración y control de errores {#depuración-y-control-de-errores}

La depuración y el control de los errores en **Bash** son fundamentales para que tus scripts sean confiables y fáciles de mantener y más seguros, podemos verlo con un portero... de discoteca, nunca he ido a una discoteca pero me han dicho que es así... está bien las películas me lo han dicho ¿contento? 😿.


### Set {#set}

Esta herramienta incorporada en el todo poderoso **Bash**, te permite cambiar como se comporta el script, de dos formas y interesantes, imprimir los comandos que se están ejecutando y detectar los errores que surgen dentro del script.

```bash
#!/bin/bash

set -x           # Esto imprime cada comando antes de ejecutarlo
set -e           # Termina el script si algún comando falla (exit != 0)
set -u           # Termina si usas una variable no definida
set -o pipefail  # Falla si algún comando en un pipeline falla
```

{{< admonition note "Notita" false >}}
Te recomiendo usar una combinación de los mismos para que puedas asegurar la integridad del script.

Ejemplo;

```bash
#!/bin/bash

set -euo pipefail
```

La X es x en la vida así que no se usa amenos que estemos depurando, ya que esta nos va a imprimir letras raras y simbolos chinos.

{{< /admonition >}}


### Trap {#trap}

Este comando nos permite capturar señales del sistema o errores y ejecuta alguna acción especifica cuando ocurre. Este comando es muy útil sí manejas errores de forma centralizada, limpias archivos temporales o detectas interrupciones por par del usuario. El comando `trap` funciona mucho mejor siempre que uses el `set -e` para que el script falle automáticamente cuando un comando falla.

De esta forma podemos capturar cualquier error de ejecución en el script, donde imprimimos el mensaje "Ocurrió un error" y finalizamos retornando la el código 1.

```bash
#!/bin/bash

set -e

trap 'echo "Ocurrió un error, ¡corre, llama al senior que se cayó producción!"; exit 1' ERR
```

De esta forma podemos capturar la señal de `interrupt` o lo que es lo mismo, de interrupción, donde imprimimos el mensaje "Script interrumpido por el usuario" y retornamos el código 2.

```bash
#!/bin/bash

set -e

trap 'echo "Script interrumpido por el usuario, no puedes ser más tontisimo"; exit 2' INT
```

Con este ejemplo sencillo puedes ver el funcionamiento de estos dos errores;

```bash
#!/bin/bash

set -e

trap 'echo "Ocurrió un error inesperado, muy raro, hay que depurar"; exit 1' ERR
trap 'echo "Interrumpido por el usuario, pero que aguafiestas"; exit 2' INT

echo "Simulando algo... tal vez teniendo una vida"
sleep 3

# Forzamos un error
false

echo "Esto no se mostrará, amenos que quites el false"
```

{{< admonition note "Notita" false >}}
Para este ejemplo, si lo dejas quieto el error dos (2) se ejecutará luego de tres (3) segundo, en cambio sí lo cancelas con `Ctrl + C` antes de que se cumplan esos tres (3) segundo ejecutará el primer error.
{{< /admonition >}}


### Verificar el código de salida de comandos {#verificar-el-código-de-salida-de-comandos}

De esta forma nosotros podemos hacer un control de errores de una forma un tanto "manual", lo que nos da cierto control.

```bash
#!/bin/bash

cp archivo.txt /ruta/de/destino
if [ $? -ne 0 ]; then
  echo "Error al copiar el archivo"
  exit 1
fi
```

También podemos hacerlo un poco más limpio usando las pipetas;

```bash
#!/bin/bash

cp archivo.txt /ruta/destino || {
  echo "Fallo al copiar el archivo"
  exit 1
}
```


### Funciones con código de error {#funciones-con-código-de-error}

```bash
#!/bin/bash

descargar_archivo() {
  curl -O "$1" || return 1
}

descargar_archivo "https://www.vt100.net" || {
  echo "Error al descargar, no seas cochino y no veas esas cosas tan sexys"
  exit 1
}
```


## echo "Bye bye" {#echo-bye-bye}

Bueno, como palabras finales, quiero dejar en claro que este post está escrito con un tono de humor algo curioso y raro, pero con la alegría genuina de poder enseñarte de una forma más amena. Así fue como yo aprendí.

En esta entrega de **Bash** es una entrega que pretende ondear más en que podamos reutilizar nuestros scripts y poder definir tareas que podamos reutilizar, ya que en lo personal soy muy de reutilizar lo que ya tenemos aunque también soy el típico que quiere reinventar la rueda siempre que pueda, pero tenemos que saber cuando podemos darnos el gusto de experimentar y cuando tenemos que saber reutilizar nuestras herramientas.

Aquí espero que hayas aprendido lo básico de como se deben de manejar mejor una interacción más amena con capa 8 y la reutilización de los mismos códigos para que así puedas trabajar con funcionalidades las veces que necesites.

Así que nada… vamos improvisando sobre la marcha.

>🙏 *Pensamiento final*
>
>Que **San Ignucio** te proteja del ~software privativo~, <br>
>que tu `terminal` nunca se congele, <br>
>y que los `bugs` huyan al verte compilar. <br>
>
>**Recuerda**: <br>
>*"Benditos sean los que comparten su `código`,
>porque de ellos será el reino del `software libre`"*
>
>¡Nos leemos pronto, con terminal abierta y corazón libre! 🐧✨

