DanLevy.net

Quiz: Dominio de Bashy Shell

¿Puedes hablar con las computadoras? ¿Así, bien?

¡Pon a prueba tus habilidades de scripting en Bash con estas 16 preguntas!

Cubre variables, bucles, condicionales, manipulación de cadenas, funciones y los trucos de sintaxis, desde lo básico hasta lo más engorroso.

Afila (o demuestra) tus habilidades de scripting en shell!

¿Cómo se definen las variables en Bash?

En Bash, las variables se declaran sin espacios alrededor del signo =. Por ejemplo:

Terminal window
name=Alice

Esto asigna el valor "Alice" a la variable name.

Nota: $name se usa para referenciar o leer el valor de una variable.

Añadir espacios hace que el shell interprete el comando como un programa a ejecutar, lo que no deseas al establecer una variable.

Además, Bash distingue mayúsculas y minúsculas, así que name, NAME y Name son variables diferentes.

Finalmente, las variables no pueden contener espacios ni guiones (-) en sus nombres. Usa guiones bajos (_) o camelCase en su lugar.

¿Qué imprimirá It's 🔨 Time!?

Lo sé. Es una locura lo rápido que el escape complica el análisis de cadenas. Imagina escapar otros lenguajes dentro de strings de Bash, con todas esas comillas, apóstrofes y símbolos $ que te joden. 🫠

Las comillas simples necesitan escaparse dentro de cadenas entre comillas simples. La secuencia de cerrar‑comilla, escapar‑comilla, volver‑a‑abrir ('\'') permite la salida de:

It's 🔨 Time!

Hay otras formas de manejar esto, pero esta es la más común.

¿Qué imprimirá este comando?

Terminal window
echo c{a,b}t

La expansión con llaves {} genera múltiples versiones del contexto de su cadena, una (o más) para cada valor separado por comas o patrón.

Aquí, c{a,b}t se expande a:

cat cbt

Ahora, ¿qué imprimirá esto?

Terminal window
price="$100"
echo "Cost: $price"

Las variables numeradas tienen un significado especial. En este caso, $1 es una variable especial que contiene el primer argumento pasado al script o función.

Como estamos ejecutando el script en un REPL, no hay argumentos, así que $1 está vacío. El texto restante 00 se imprime tal cual.

Para imprimir un carácter literal $, usa comillas simples o escápalo con una barra invertida (\\):

Terminal window
price="\$100"
echo "Cost: $price"

¿Qué está pasando aquí?

Terminal window
str="Bark bark"
echo ${str/bark/meow}

La sintaxis ${var/pattern/replacement} reemplaza la primera aparición de pattern con replacement. Aquí, la salida es:

Bark meow

Es sensible a mayúsculas y minúsculas. Para manejar tanto bark como Bark, usa un patrón como ${var/[Bb]ark/Bark} o normaliza la cadena antes de la sustitución.

Para reemplazar todas las apariciones, usa ${var//pattern/replacement}.

Para reemplazar desde el comienzo de la cadena, usa ${var/#pattern/replacement}.

Para reemplazar desde el final de la cadena, usa ${var/%pattern/replacement}.

¿Cómo puedes obtener la longitud de una variable en Bash?

La sintaxis ${#username} devuelve la longitud de username.

Por ejemplo:

Terminal window
username="@justsml"
echo ${#username} # => 8

Aunque wc funcionaría, técnicamente no forma parte de Bash.

La utilidad wc es una vieja broma interna que se refiere a “water closet”, o baño. ¡BROMA! ¿Alguien lee esto?

En realidad wc es un comando antiguo de POSIX (y de los días de AT&T Unix). Es la abreviatura de “word count” y puede contar líneas, palabras y caracteres en un archivo o flujo de entrada.

¿Qué imprime este script si el archivo cats.txt EXISTE?

Terminal window
if [ -e cats.txt]; then
echo "File exists"
else
echo "File does not exist"
fi

¿Notaste el espacio faltante antes del corchete de cierre?

Bash es bastante quisquilloso aquí: se requieren espacios dentro de las expresiones entre corchetes.

Como el espacio faltante hace que el comando [ no vea el ] de cierre, Bash muestra un diagnóstico, trata la prueba como fallida y continúa al bloque else.

La sintaxis correcta es:

Terminal window
if [ -e example.txt ]; then
echo "File exists"
else
echo "File does not exist"
fi

Nota: Los corchetes dobles [[ ]] están recomendados para expresiones condicionales. Ver BashFAQ.

¿Cómo podemos comparar cadenas en Bash?

Terminal window
cat1="Rosie"
cat2="Sunflower"
if [ "$cat1" === "$cat2" ]; then
echo "Same cat"
else
echo "Different cats"
fi

¡Otro error de sintaxis de prueba!

¿Capturaste el operador === inválido?

Quizás estabas pensando en JavaScript…

Con [ ... ], Bash informa un diagnóstico y la condición es falsa, por lo que la rama else imprime Different cats. En Bash, usa = o == para comparaciones de igualdad.

¿Qué imprimirá este script?

Terminal window
function greet () {
echo "$1"
}
greet Hi Dan

Las funciones en Bash pueden aceptar argumentos. La variable $1 contiene el primer argumento pasado a la función.

Recuerda, $0 es el nombre del script, $1 es el primer argumento, $2 es el segundo, y así sucesivamente. Los espacios separan los argumentos. Así, greet Hi Dan pasa "Hi" como primer argumento. Para pasar "Hi Dan" como un solo argumento, deberías citarlo: greet "Hi Dan".

¿Qué operador conecta la salida de un comando con la entrada del siguiente comando?

El operador | conecta la salida de un comando con la entrada de otro. Por ejemplo:

Terminal window
echo "Mr. Levy 👨🏻‍🔬" | wc -m
# => 14

¿Cómo funciona la aritmética en Bash?

La sintaxis (( )) realiza cálculos enteros en Bash.

Puede usarse para cálculos simples:

Terminal window
((result = 2 + 2))
echo $result # => 4

O para expresiones condicionales:

Terminal window
if (( 2 > 1 )); then
echo "2 is greater than 1"
fi

Para aritmética de punto flotante, considera usar bc o awk.

¿Cuál de estos multiplica correctamente 10 y 0.5, imprimiendo 5?

La sintaxis (( )) SÓLO realiza aritmética entera. Ya sabes, números sin decimales, ¡sin punto flotante!

Bash (quizá sorprendentemente) no tiene soporte integrado para aritmética de punto flotante.

La solución más común es usar las utilidades GNU bc o awk.

¿Qué hace el : en este script?

Terminal window
rosie="Bad cat, good cat"
echo ${rosie:9}

La sintaxis ${var:offset} extrae una subcadena que comienza en offset. Aquí, la salida es:

good cat

Para extraer una subcadena de longitud específica, usa ${var:offset:length}.

Para extraer desde el final de la cadena, usa ${var: -offset}. (¡Nota el espacio antes del -!)

¿Qué NO ❌ es una palabra clave de bucle en Bash?

each no es una palabra clave de bucle en Bash. Las principales palabras clave de bucle son for, while y until.

Mientras do no es técnicamente una palabra clave de bucle, es una parte clave de la sintaxis del bucle.

¿Qué opción ejecutará el comando ls -l y devolverá la salida?

La sintaxis $(ls -l) ejecuta el comando dentro de los paréntesis y sustituye la salida. Por ejemplo:

Terminal window
echo "Today is $(date +%F)"
# => Today is 2029-12-31

La primera opción usa comillas simples ', no acentos graves. Esto impide la expansión, de modo que '$(date +%F)' simplemente imprimirá la cadena literal $(date +%F).

Aunque todavía se admite usar acentos graves (`ls -l`) para ejecutar comandos, recientemente se ha convertido en una especie de anti‑patrón (en algunos contextos). La mayoría recomienda usar $(command) para mejor legibilidad y consistencia con diferentes shells y versiones.

Las llaves ${} se usan para expansión de variables, no para sustitución de comandos.

El carácter % no se usa para sustitución de comandos.

¿Qué operador se usa para combinar la salida de error con la salida estándar?

El operador 2>&1 redirige la salida de error estándar (descriptor de archivo 2) a la salida estándar (descriptor de archivo 1). Esto es útil para capturar los mensajes de error en el mismo flujo de salida que la salida normal.

El operador 1>&2 redirige la salida estándar a la salida de error, sin embargo, la pregunta pedía cómo redirigir la salida de error a la salida estándar.

Para aprender más sobre lo que ocurre bajo el capó, consulta la excelente FAQ de redirección de Greg.

Además, gracias al usuario de Reddit u/OneTurnMore por sugerir mejoras en el texto.

¿Te dejó el Quiz de Bash hecho polvo?

¡Déjame tu comentario abajo!

Lecturas adicionales

Refuerza tus habilidades en Bash con los siguientes recursos: