Una guía simple para la programación de scripts en Linux con Bash

¿Alguna vez te has encontrado con ganas de aprender más sobre la programación de scripts de shell de Linux, pero no estabas seguro de por dónde empezar? ¿Eres relativamente nuevo en el mundo de los sistemas operativos basados en Unix y deseas ampliar tus habilidades para realizar algo de programación básica de shell? Este tutorial para principiantes repasará los conceptos básicos de la programación de scripts de shell de Linux con Bash, incluyendo la creación y ejecución de un script, así como el trabajo con cadenas y bucles.

La programación de scripts de shell se utiliza para automatizar tareas administrativas comunes

Independientemente del sistema operativo, se utilizan scripts de shell para automatizar tareas administrativas repetitivas. Por ejemplo, en Windows puedes renombrar archivos usando el Explorador de Archivos. Pero si necesitas renombrar muchos archivos, sería una tarea que consumiría mucho tiempo usar la interfaz gráfica de shell. PowerShell te permite automatizar la tarea y repetirla de manera confiable.

Publicidad

En sistemas operativos basados en Linux, se utilizan Bash y otros shells para automatizar tareas como trabajar con archivos, modificar la configuración del sistema y muchas otras tareas que de otra manera podrían realizarse escribiendo comandos individuales.

Lo que necesitas para aprender la programación de scripts de shell Bash

Para escribir y ejecutar un script Bash, solo necesitas tres cosas:

  • Cualquier editor de texto plano, como Notepad, Text Editor, TextEdit, vi, emacs, o Visual Studio Code.
  • terminal emulator, an application that comes preinstalled with most operating systems and is often called Terminal, Console, or Command Prompt.
  • Bash en sí mismo.

El emulador de terminal es donde escribirás las órdenes y las ejecutarás presionando Enter o Return. En cuanto a Bash, si tienes preinstalado depende de tu plataforma:

  • En macOS, Bash es preinstalado. En versiones más recientes, la Z shell (zsh) es la shell predeterminada, y esto es correcto. Siempre que Bash esté instalado, puedes ejecutar scripts de Bash desde zsh también.
  • Linux distribuciones generalmente tienen Bash instalado. (Puedes verificar buscando si tu sistema incluye el archivo /bin/bash.) Android es un caso especial que no llega con Bash. Hay pasos para obtener Bash en Android, que este artículo no entrará.
  • Windows no viene con Bash incluido. PowerShell es la shell de línea de comandos predeterminada en Windows. Necesitarás instalar una distribución de Linux bajo el Windows Subsystem for Linux (WSL) para ejecutar Bash.

Para encontrar la versión de tu Bash, ejecuta el comando bash –version. Aunque incluso las versiones antiguas de Bash te proporcionan mucha potencia, tanto Bash 3 como 4 introducen notaciones abreviadas agradables para ciertos comandos básicos. Si un comando requiere una de estas versiones de Bash, se mencionará a continuación.

Publicidad

¿Qué es una shell?

En el mundo de la informática, una shell es un programa que sirve como interfaz para el sistema operativo subyacente. Una shell puede ser una interfaz de usuario gráfica (GUI), como la shell de Windows.

Lenguajes de scripting de shell

Sin embargo, las personas generalmente utilizan el término para referirse específicamente a una interfaz de línea de comandos (CLI) — una interfaz que consiste en líneas de texto con las que interactúas utilizando únicamente el teclado. Aquí tienes algunos ejemplos de lenguajes de scripting de shell para sistemas operativos *nix:

Aquí nos centraremos en el shell Bash. Es un shell Unix gratuito y popular preinstalado en la mayoría de las distribuciones Linux y en macOS.

¿Qué es un script de shell?

Los shells tienen su propio lenguaje de programación. Utilizas este lenguaje para enviar comandos al shell, los cuales este ejecuta. Puedes escribir estos comandos directamente en el shell, o puedes guardarlos en un archivo — un script — y luego ejecutar ese archivo desde el shell. La sintaxis para escribir comandos es la misma en ambos casos.

Publicidad

Este artículo cubrirá los conceptos básicos de scripting de shell para crear este archivo.

Conceptos básicos de scripting de shell

Comencemos con algunos conceptos básicos de scripting de shell. Para escribir un script simple aprenderemos algunos comandos básicos de scripting de shell en Linux:

  1. Cree un nuevo archivo de texto vacío en un editor de texto.
  2. Escriba #!/bin/bash como primera línea.
  3. Escriba sus comandos debajo de eso.
  4. Guarde el archivo, preferiblemente con la extensión “.sh” o sin ninguna extensión.

La línea #!/bin/bash se conoce como “shebang”. Indica a su shell que este script debe ejecutarse en Bash y debe ser la primera línea en su script. Si cambia a un shell diferente, su script seguirá ejecutándose en Bash.

Para probar este proceso usted mismo, cree un archivo llamado ‘hello_world’ en su directorio de inicio:

#!/bin/bash
echo "hello world"

¡Eso es todo! ¡Ha creado un script de Bash!

Our “hello world” script is just a simple text file

Antes de poder ejecutarlo, probablemente necesitará cambiar los permisos del archivo.

Estableciendo permisos para ejecutar un script de shell usando chmod

Para modificar los permisos en nuestro archivo ‘hello_world’, debería ejecutar este comando específico en su emulador de terminal. Esto le otorga al usuario que posee el archivo el permiso para ejecutarlo.:

chmod u+x 'hello_world'
Running our script without vs. with the “execute” permission

Si solo quieres ejecutar tu script de shell, puedes saltar a la siguiente sección. Para aquellos curiosos sobre el comando chmod, chmod es corto para “cambio de modificación”, y sirve para cambiar los “modos” de archivo (o permisos) en Unix. En sistemas operativos tipo Unix, puedes establecer permisos de archivo para 3 clases de usuarios:

  • El usuario que posee el archivo (representado por u en chmod).
  • El grupo que posee el archivo (g).
  • Otros (o).

Con el comando chmod, también puedes usar a para referirte a todos ellos.

Cada archivo tiene 3 tipos de permisos (o “modos”):

  • Lectura (r)
  • Escritura (w)
  • Ejecución (x)

Y también puedes añadir (+) o eliminar (-) permisos.

El primer parámetro en chmod es una combinación de estos tres: usuario primero, acción segundo y modo tercero. Aquí tienes algunos ejemplos de comandos:

  • chmod gu+rw 'hello_world' añadiría permisos de lectura y escritura para el propietario y el grupo propietario.
  • chmod a-x 'hello_world' eliminaría los permisos de ejecución para todos.
  • chmod u+rwx 'hello_world' 'hello_world_2' daría al propietario el permiso de leer, escribir y ejecutar los archivos “hello_world” y “hello_world_2”.

Solo hemos cubierto lo básico del comando chmod aquí. También hay una forma más complicada, pero menos explícita, de definir estos modos (la “notación numérica”), así como un comando diferente que puede usar para ver qué permisos tienen sus archivos (ls -l). No profundizaremos en estos temas aquí.

Ejecutar un script de shell

Es hora de ejecutar nuestro primer script. En general, para ejecutar un script, simplemente escriba su ruta en el emulador de terminal y presione enter.

./hello_world

Puede usar la ruta relativa o la absoluta. Al usar la ruta relativa, siempre use ./ al principio de su comando: Esto le indica al terminal que busque en la carpeta actual (representada por '.'), en lugar de en los directorios definidos en la variable de entorno PATH.

Just typing the script name doesn’t work, but running its relative or absolute paths does

Usar comentarios para anotar su script

Todo lo que viene después de un # en una sola línea en un script de Bash se considera un comentario. Estos pueden ser útiles para comunicar qué hace una línea compleja o dar un resumen de qué hacen las partes importantes de su script.

Por ejemplo:

#!/bin/bash

#
# This shell script prints "hello world".
#

echo "hello world" # This line prints "hello world".

Una introducción a las variables

Al escribir scripts, puede ser útil definir variables. En Bash, esto se hace escribiendo el nombre de la variable y el valor, separados por un signo igual: VARIABLENOMBRE='VALOR'.

No se deben colocar espacios junto al signo igual — Bash pensaría que quieres ejecutar un proceso en su lugar.

Utiliza comillas simples para rodear el valor y evitar que Bash lo interprete como otra cosa. En Bash, las variables no tienen tipos — todo es básicamente una cadena de texto. Depende de los programas de Bash interpretar la cadena como un tipo diferente, como un número.

Para hacer referencia al valor de una variable, utiliza el nombre de la variable precedido por el signo de dólar: $VARIABLENOMBRE.

Para probar esto en la práctica, puedes cambiar tu script a esto:

#!/bin/bash
HELLO="hello variable world"
echo $HELLO # should print "hello variable world"

Recibiendo argumentos

Las palabras individuales que escribes al escribir un comando se llaman argumentos. En nuestro ejemplo chmod u+x 'hola_mundo'chmodu+x, y 'hola_mundo' son tres argumentos diferentes. chmod es el nombre del comando mientras que u+x y hola_mundo son llamados parámetros — argumentos que proporcionan información adicional al comando.

En tu script, puedes acceder a estos argumentos a través de variables. Para evitar conflictos con variables locales, estas variables se nombran usando números — $0 se refiere al nombre del comando, $1 es el siguiente argumento que le sigue, $2 el siguiente, y así sucesivamente.

Vamos a probar esto:

#!/bin/bash
HELLO="hello $1 world"
echo $HELLO

Ahora, ejecuta este script con estos parámetros:

./hello_world bash script

La salida debería ser hola mundo bash, utilizando el primer parámetro y ignorando el segundo.

Si querías que script de bash se viera como un solo parámetro, necesitarías ponerlo entre comillas: 

./hello_world 'bash script'
Words separated by a space are considered as several arguments, except when in quotes

Usando la declaración if para ejecutar código condicionalmente

Una de las cosas fundamentales que los programadores quieren hacer dentro de un script es ejecutar un fragmento de código solo si se cumple una condición. Bash tiene la declaración if para eso:

NUM=$RANDOM
if (( $NUM % 2 )) # if CONDITION
then
    echo "$NUM is odd"
fi # this is how you end an if statement

Consejo: A partir de aquí, se asume que estos ejemplos forman parte de un script más grande y se omite el #!/bin/bash al principio. ¡No lo olvides como primera línea de tu script, sin embargo!

También puedes utilizar else dentro de una declaración if para especificar qué hacer si una condición no se cumple, o una elif (abreviatura de “sino si “) para especificar otra condición si la primera no se cumple:

NUM=$RANDOM
if [ $NUM -eq 12 ]
then
    echo "$NUM is my favorite number"
elif (( $NUM % 2 ))
then
    echo "$NUM is odd"
else
    echo "$NUM is even"fi

fi‘ se utiliza para cerrar la declaración if.

Consejo: Si no estás seguro de cómo escribir la condición en sí, consulta la notación del test, paréntesis simples ([]) y paréntesis dobles ((())).

The output of our script depends on the value of a random variable

Repetir una serie de comandos usando un bucle for

Ahora que hemos cubierto la ejecución condicional del código, veamos cómo ejecutar código un número determinado de veces siempre que se cumpla una condición.

El for loop es perfecto para esta tarea, específicamente su sintaxis de “tres expresiones”. La idea detrás de esto es asignar una variable específica del bucle y cambiarla gradualmente hasta que se cumpla una cierta condición. Así es como está estructurado:

for (( ASSIGNMENT_EXPRESSION ; CONDITION_EXPRESSION ; UPDATE_EXPRESSION ))
do
    COMMANDS
done

Por ejemplo, si deseas que un bucle se ejecute 10 veces con valores para i que van de 0 a 9, tu bucle for podría verse así:

for (( i=0; i<10; i++ ))
do
    echo $i
done

Vamos a analizarlo:

  • i=0 is the assignment expression here. It’s run only once before the loop is executed, which is why it’s useful for initializing a variable.
  • i<10 is our condition expression. This expression is evaluated before each iteration of a loop. If it is equal to zero (which means the same as “true” in Bash), the next iteration is not run.
  • i++ is our update expression. It’s run after each iteration of a loop.
The structure of our for loop

Ciclar a través de elementos en una lista

Además de la sintaxis de tres expresiones, también puedes usar la in palabra clave para definir un bucle for. Esta sintaxis alternativa se utiliza para iterar a través de una serie de elementos.

El ejemplo más básico es simplemente enumerar el conjunto de elementos por los que deseas iterar después de la palabra clave in, separados por espacios. Por ejemplo:

for i in 0 1 2 3 4 5 6 7 8 9 # space-separated list items
do
    echo $i
done

También puedes iterar a través de los elementos generados por un comando:

for i in $(seq 0 1 9)

La notación $() se utiliza para la sustitución de comandos en general — ejecuta un comando y su salida se utiliza como entrada para el comando padre que lo rodea.

Si estás iterando a través de enteros, es preferible utilizar la sintaxis de rango integrada en Bash, la cual es más eficiente que el comando seq. Sin embargo, esta sintaxis solo está disponible en versiones más recientes de Bash:

  • for i in {0..9}, disponible en Bash 3.
  • for i in {0..9..1}, disponible en Bash 4, donde el último número representa el incremento.

De la misma manera, también puedes iterar a través de cadenas de texto:

for s in 'item1' 'item2' 'item3'

Utilizando el globbing para obtener archivos que coinciden con un patrón

Uno de los casos de uso más comunes para los bucles for discutidos en la sección anterior es iterar a través de archivos individuales.

Para abordar esto, primero necesitamos cubrir las “expansiones de globo”. Esta es una característica en Bash que te permite especificar nombres de archivos utilizando coincidencia de patrones. Hay caracteres especiales llamados comodines que utilizas para definir esos patrones.

Antes de profundizar en esto, veamos algunos ejemplos específicos:

  • echo *: Un comando que devuelve los nombres de todos los archivos en su directorio actual, excepto los ocultos.
  • echo *.txt: Un comando que devuelve los nombres de todos los archivos no ocultos con extensión txt en su directorio actual.
  • echo ????: Un comando que devuelve todos los nombres de archivos de cuatro letras en su directorio actual.

Los comodines que usamos fueron * y ? aquí. También hay un comodín más que no utilizamos. Aquí tienes una visión general:

  • El asterisco (*) representa cualquier número de caracteres (incluido 0) en un nombre de archivo o directorio.
  • El signo de interrogación (?) representa un solo carácter en un nombre de archivo o directorio.
  • El doble asterisco (**) representa cualquier número de caracteres en una ruta de archivo completa. Es una característica en Bash 4 y versiones posteriores y debe habilitarse ejecutando shopt -s globstar.
  • Los corchetes cuadrados ([]) se utilizan para representar un carácter dentro de un conjunto de símbolos en un nombre de archivo o directorio. Por ejemplo, [st]ake encontraría archivos llamados sake o take, pero no stake.

Tenga en cuenta que todos los archivos ocultos (que son archivos con nombres que comienzan con un punto .) se ignoran al usar la expansión de comodines.

La notación de corchetes permite un poco más de complejidad, incluyendo:

  • Rangos definidos por el primer y último valor, por ejemplo [1-8]
  • Eliminación de ciertos caracteres usando ! como el primer carácter dentro de los corchetes, por ejemplo [!3].

Para tratar uno de estos caracteres especiales como un carácter normal sin ningún significado, simplemente coloca una barra invertida antes, por ejemplo \?.

A few examples of globbing

Iterando a través de archivos usando un bucle for

Ahora que hemos cubierto lo básico de la expansión de globos, veamos cómo utilizarlo para iterar a través de archivos.

Simplemente podemos usar los operadores de globos en el mismo bucle for. Aquí tienes un ejemplo sencillo de un bucle que imprime el nombre de cada archivo en el directorio actual:

for f in *
do
    echo $f
done

Para imprimir los nombres de cada archivo en el directorio actual y sus subdirectorios, verifica que estás usando Bash 4.0 o superior ejecutando bash --version, y luego puedes ejecutar el siguiente comando:

shopt -s globstar # enables using **
for f in **
do
    echo $f
done

Consejo: Si estás usando una versión más antigua de Bash, no podrás utilizar la expansión de globos con un bucle for para esto. Tu mejor opción sería el comando find, pero no lo cubriremos en este artículo.

Estos son, por supuesto, solo algunos de los bucles más simples que puedes ejecutar, pero hay mucho más que puedes hacer. Por ejemplo, para renombrar todos los archivos JPG en una carpeta para darles un nombre de archivo secuencial consistente, podrías ejecutar:

i=1
for f in *.jpg
do
    mv -i -- "$f" "image_$i.jpg"
    let i=i+1
done
Checking the Bash version, then running our script

Ejecutar código mientras una condición es verdadera

El bucle for no es el único tipo de bucle que podemos usar en Bash, también tenemos while: Este tipo de bucle se ejecuta mientras una condición específica es verdadera.

La sintaxis es similar a la sintaxis del bucle for:

while CONDITION
do
    COMMANDS
done

Para un ejemplo práctico, así es como podrías leer un archivo línea por línea (sin espacios en blanco al principio o al final) hasta que llegues al final del archivo:

while read -r line
do
    echo "$line"
done < FILENAME # Replace FILENAME with the path to a text file you'd like to read
Using a while loop inside our script to have it print itself

También puedes reemplazar un bucle for con un bucle while, por ejemplo, para iterar de 0 a 9:

i=0
while [ $i -lt 10 ]
do
    echo $i
    let i=i+1
done

Y también podrías teóricamente ejecutar un bucle para siempre. Aquí tienes un ejemplo de comando:

while true
do
    echo "running forever"
done

Consejo: Para detener el script, simplemente presiona Ctrl+C.

Aunque este bucle infinito puede parecer inútil a primera vista, en realidad puede ser bastante útil, especialmente cuando se combina con la declaración break.

Salir de un bucle

La declaración break se utiliza para salir de un bucle.

Esto te permite ejecutar un bucle infinito y salir de él cuando surjan condiciones de salida.

Para ver un ejemplo simple, podemos replicar nuestro bucle que se ejecuta desde 0 hasta 9 con un bucle infinito como este:

i=0while true
do
    if [ $i -eq 10 ]
    then
        break
    fi
    echo $i
    let i=i+1
done

Si tienes varios bucles while anidados, puedes agregar un número después de la instrucción break para mencionar desde qué nivel de bucle deseas salir: break 1 es lo mismo que break y saldrá del bucle más cercano, break 2 saldrá un nivel por encima del bucle, etc.

Veamos un ejemplo rápido, esta vez con bucles for, iterando a través de todas las combinaciones de palabras de cuatro letras hasta llegar a la palabra “bash”:

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

A related keyword that’s also worth a mention is continue, which skips to the next iteration of the loop. Just like break, it also takes an optional numeric argument that corresponds to the loop level.

Aquí tienes un ejemplo tonto donde saltamos todas las palabras con Es en nuestra lista de palabras cortas de cuatro letras:

for l4 in {a..z}
do
    if [ $l4 = "e" ]
    then
        continue
    fi
    for l3 in {a..z}
    do
        if [ $l3 = "e" ]
        then
            continue
        fi
        for l2 in {a..z}
        do
            if [ $l2 = "e" ]
            then
                continue
            fi
            for l1 in {a..z}
            do
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

También podríamos ejecutar todas estas instrucciones continue en el nivel más profundo del bucle:

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                if [ $l4 = "e" ]
                then
                    continue 4
                fi
                if [ $l3 = "e" ]
                then
                    continue 3
                fi
                if [ $l2 = "e" ]
                then
                    continue 2
                fi
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done
Our script stops once it generates the word “bash”

Cómo obtener la entrada del usuario en un script de shell

A veces, querrás que el usuario interactúe directamente con tu script en lugar de solo usar argumentos iniciales del script. Ahí es donde entra en juego el comando read.

Para obtener la entrada del usuario y guardarla en una variable llamada NAME, usarías este comando:

read NAME 

Esta es la forma más simple del comando, consistente únicamente del nombre del comando y la variable en la que quieres guardar la entrada.

Con más frecuencia, sin embargo, querrás solicitar al usuario para que sepa qué escribir. Puedes lograrlo con el argumento -p, luego escribes el aviso que prefieras.

Así es cómo podrías pedir un nombre, asignándolo a una variable llamada NAME:

read -p "Your name: " NAME
echo "Your name is $NAME." # this line is here just to show that the name has been saved to the NAME variable
The script saves our input to a variable and then prints it

Imprimir caracteres especiales en una cadena

Hay varios caracteres en Bash de los que tienes que tener cuidado al usar. Por ejemplo, espacios dentro de nombres de archivos, comillas dentro de cadenas o barras inclinadas casi en cualquier lugar.

Para indicarle a Bash que ignore su significado especial en ciertos lugares, puedes “escapar” de ellos o envolverlos en una comilla literal.

Escapar de un carácter especial significa decirle a Bash que lo trate como un simple carácter sin ningún significado especial. Para hacerlo, escribe una barra inclinada antes de ese carácter.

Digamos que tenemos un archivo llamado img \ 01 *DRAFT*, por ejemplo. En Bash, podríamos referirnos a él de esta manera:

img\ \\\ 01\ \*DRAFT\*

Aquí tienes una lista no exhaustiva de caracteres especiales en Bash:

  • Espacios en blanco: espacio, tabulación, línea en blanco
  • Comillas: ”, “”
  • Paréntesis, llaves y corchetes: ( ), { }, [ ]
  • Tuberías y redirecciones: |, <, >
  • Comodines: *, ?
  • Varios: !, #, ;, =, &, ~, `
  • El carácter de escape en sí mismo: \

Si eres nuevo en Bash, sin embargo, puede ser un problema recordar qué caracteres tienen un significado especial. Como tal, en muchas situaciones, puede ser más fácil usar una comilla literal: Simplemente rodea el texto que contiene cualquier carácter especial con comillas simples, y todos los caracteres especiales dentro de esas comillas serán ignorados.

Aquí tienes cómo se vería para nuestro ejemplo:

'img \ 01 *DRAFT*'

¿Y si quieres usar un carácter especial, pero escapar a los demás? Podrías escapar cada otro carácter usando una barra invertida, pero también puedes ahorrarte el problema y rodear todo excepto ese carácter especial con comillas literales.

Por ejemplo, digamos que tienes varios archivos llamados img \ 01 *v1 DRAFT*, img \ 01 *v2 DRAFT*, img \ 01 *ROUGH DRAFT*, etc., y quieres usar una expansión de comodines para que coincidan con todos esos nombres de archivo. Así es como podrías escribirlo:

'img \ 01 *'*' DRAFT*'
This glob expansion finds all of our 3 oddly-named files

Si lo que necesitas escribir contiene una comilla simple, por ejemplo, img \ 01 *’FINAL’*, puedes usar una estrategia similar, combinando cadenas literales y escapando:

'img \ 01 '\''FINAL'\'

Cómo concatenar cadenas en Bash

Digamos que tienes dos o más variables de cadena, un nombre y un apellido, por ejemplo:

FIRST_NAME="Johnny"LAST_NAME="Appleseed"

Para combinar esas variables en una sola cadena, quizás con un delimitador personalizado, simplemente crea una nueva cadena que consista en esas dos variables:

NAME="$LAST_NAME"', '"$FIRST_NAME"

También puedes usar comillas dobles con variables en línea para esto, usando llaves para separar los nombres de variable del texto circundante:

NAME="${LAST_NAME}, ${FIRST_NAME}"

Bash también permite el uso del operador += para agregar texto a una cadena, así:

NAME='Appleseed'NAME+=', 'NAME+='Johnny'
Examples of different ways of stringing together text

Ejecutar comandos dentro de una cadena

Bash también te permite usar la salida de un comando dentro de una cadena, también conocido como sustitución de comando. Simplemente rodea tu comando con $(). Por ejemplo, para imprimir una marca de tiempo actual, puedes ejecutar:

echo "Current timestamp: $(date)"
Using command substitution to print the current timestamp

También puedes recordar esta sintaxis de un ejemplo anterior de bucle for, cuando iteramos a través de una secuencia de enteros de 0 a 9:

for i in $(seq 0 1 9)
do
    echo $i
done

El comando sustituido se ejecuta en un subshell. Esto significa que, por ejemplo, cualquier variable creada durante el comando no afectará el entorno en el que estás ejecutando tu script.

Estableciendo y devolviendo códigos de salida en un script de shell

Para un script más complejo, es costumbre que devuelva un exit código — un número entre 0 y 255 que le dice a las personas si el script se ejecutó correctamente o encontró un error.

En cuanto a qué números utilizar, el manual oficial de Bash especifica estos:

  • 0: Programa ejecutado con éxito.
  • 2: Programa utilizado incorrectamente (por ejemplo, debido a argumentos inválidos o perdidos).
  • 1 y 3-124: Errores definidos por el usuario.
  • 126: Comando no es ejecutable.
  • 127: Comando no encontrado.
  • 125 y 128-255: Estados de error que usa el shell. Si un proceso es detenido por una señal N, el estado de salida es 128 + N.

Como puedes ver, todos los números aparte de 0 indican algún tipo de error. El código de salida 1 se utiliza comúnmente para errores generales. En la mayoría de los casos, no necesitarás usar ningún código de salida por encima de 2.

Para devolver un código de salida desde tu script, simplemente utiliza el comando exit. Por ejemplo, para salir con un código 2, escribirías exit 2.

Si no utilizas el comando exit en tu script o usas el comando sin especificar un código, se devolverá el estado de salida del último comando ejecutado en tu script.

Para obtener el código de salida del último comando ejecutado en tu shell, utiliza la variable $?: echo $?.

Cómo llamar a una función

Al escribir un script más largo o uno con fragmentos de código repetitivos, es posible que desees separar algo de código en funciones. Hay dos formatos que puedes usar para definir funciones: En ambos casos, todo el código de la función está contenido dentro de llaves y la única diferencia es la declaración de la función.

El formato más compacto utiliza paréntesis que siguen el nombre de la función para declarar una función:

function_name () {
    echo "This is where your function code goes"
}

El otro formato utiliza la palabra clave function delante de un nombre de función:

function function_name {
    echo "This is where your function code goes"
}

Las funciones deben ser declaradas antes de ser llamadas en tu script. Llamas a una función de la misma manera que ejecutas un comando regular, usando el nombre de la función como el comando:

function_name

Pasando datos a una función usando variables

En Bash, las funciones no pueden recibir argumentos. Para enviar información a una función, necesitas usar variables globales en tu script.

Por ejemplo:

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        echo "It doesn't seem like I have your name."
    else
        echo "Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

A diferencia de lo que puede estar acostumbrado en otros lenguajes, las variables que definas dentro de tu función son globales y visibles para el código fuera de tu script. Para definir una variable localizada solo a tu función (significando inaccesible para todo el código fuera de ella), usa la palabra clave local, por ejemplo local i=0.

Si deseas devolver valores desde una función, también necesitas usar variables globales. En Bash, las funciones solo pueden devolver códigos de salida, usando la palabra clave return. Veamos un ejemplo:

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        MESSAGE="It doesn't seem like I have your name."
    else
        MESSAGE="Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

echo $MESSAGE
The output of our script depends on the values entered

Resumen

La creación de scripts Bash te permite hacer muchas cosas en un sistema operativo basado en UNIX. Este artículo trató algunos conceptos básicos de los scripts Bash, incluyendo la creación y ejecución de scripts, el trabajo con cadenas y el uso de bucles en tu código. Con suerte, esto servirá como un buen comienzo para tu camino en la escritura de poderosos scripts Bash que satisfagan tus necesidades.

Sin embargo, aún hay mucho más por aprender sobre Bash, incluyendo algunos de los comandos más útiles, navegación del sistema de archivos, entre otros. Haznos saber en los comentarios sobre qué temas deberíamos hablar a continuación.

Artículo relacionado:

Source:
https://petri.com/shell-scripting-bash/