Bash vs. Dash: ¿Cuál usar para tus scripts de shell? Comparación y guía de elección
Cuando gestionas o desarrollas un sitio web, a menudo quieres automatizar pequeñas tareas repetitivas, ¿verdad? Ahí es donde los "scripts de shell" son de gran ayuda. Pero, al empezar a escribir uno, ¿alguna vez has visto esa especie de conjuro en la primera línea del archivo, como #!/bin/bash o #!/bin/sh, y te has preguntado qué diferencia hay?
La verdad es que esta diferencia es muy importante. Es un conocimiento esencial, sobre todo para evitar la tragedia de que "¡funcionaba perfectamente en mi ordenador, pero da error en el servidor!". En este artículo, explicaremos las diferencias entre dos shells muy utilizados, Bash y Dash, de una forma fácil de entender para principiantes y con código que puedes copiar y pegar para probarlo tú mismo. ¡Al leer este artículo, tú también podrás escribir scripts de shell robustos e independientes del entorno!
Para empezar, ¿qué son Bash y Dash?
Primero, presentemos a nuestros dos protagonistas (los dos shells). Conocer sus puntos fuertes y su "personalidad" es el primer paso para llevarse bien con ellos.
Bash (Bourne-Again SHell) - El compañero de todos, el shell multifuncional
Bash es el "shell de inicio de sesión" por defecto en muchos sistemas Linux y versiones antiguas de macOS. Es el que se inicia cuando abrimos una terminal. Muchas de las funciones útiles que usamos a diario sin pensar, como navegar por el historial de comandos con las flechas, autocompletar comandos y nombres de archivo con la tecla Tab, o usar colores en la terminal, nos las proporciona Bash. Se podría decir que es un shell amigable, con muchas funciones y muy adecuado para la interacción directa con humanos.
Dash (Debian Almquist SHell) - El héroe anónimo, el shell rápido y ligero
Por otro lado, la principal característica de Dash es que es extremadamente ligero y rápido. Se le han eliminado funciones innecesarias para especializarlo en la ejecución rápida de scripts. Por esta razón, se utiliza como el shell por defecto para los scripts de arranque del sistema y para aquellos que se especifican con #!/bin/sh, especialmente en sistemas operativos basados en Debian como Ubuntu. En resumen, aunque no interactuemos directamente con él muy a menudo, Dash está trabajando duro entre bastidores.
La mayor diferencia: La compatibilidad con POSIX como "dialecto" y "lenguaje estándar"
La mayor diferencia entre Bash y Dash radica en cuán fieles son a un estándar llamado POSIX.
Puede que este término técnico te haya desconcertado un poco. En pocas palabras, POSIX es como el "lenguaje estándar del mundo de los scripts de shell". Se garantiza que un script escrito en este lenguaje estándar funcionará de la misma manera en cualquier entorno (sistema operativo).
- Dash: Es muy fiel al "lenguaje estándar" POSIX. Apenas habla "dialectos".
- Bash: También habla el "lenguaje estándar", pero conoce muchos "dialectos" útiles (extensiones propias de Bash).
Las funciones prácticas que usamos normalmente en la terminal suelen ser "dialectos" de Bash. Y en muchos sistemas, /bin/sh se refiere a un shell que solo entiende el "lenguaje estándar" (como Dash). Esta es la causa principal del fenómeno "funciona en mi PC (Bash), pero no en el servidor (/bin/sh)".
Escribir #!/bin/bash en la primera línea de un script es como declarar "¡este script usa dialectos de Bash!", lo que te permite usar sus funciones avanzadas. Por el contrario, escribir #!/bin/sh es como decir "¡en lenguaje estándar, por favor!". Si quieres aumentar la portabilidad y la compatibilidad, la teoría dice que lo mejor es usar #!/bin/sh y ser consciente de escribir de forma compatible con POSIX.
【Práctica】¡Comparemos con código! ¿En qué se diferencia la sintaxis de Bash y Dash?
A partir de aquí, veamos ejemplos de código concretos para comparar los "dialectos" de Bash con la sintaxis "estándar" compatible con POSIX que también funciona en Dash. Para experimentar cómo "funciona", ¡no dudes en copiar y ejecutar el código en tu terminal!
1. Manejo de arrays
Los arrays se usan para manejar múltiples valores a la vez. En Bash se escriben de forma intuitiva, pero el estándar POSIX no tiene una especificación para arrays. Por eso, para hacer lo mismo en Dash se necesita un poco de ingenio.
La forma de Bash (dialecto)
Puedes definir un array fácilmente usando () y acceder a los elementos especificando un índice, como ${mi_array[1]}.
#!/bin/bash
# Definir un array
frutas=("manzana" "banana" "cereza")
# Imprimir el segundo elemento (el índice empieza en 0)
echo ${frutas[1]}
Resultado:
banana
La forma compatible con Dash (lenguaje estándar)
Al escribir de forma compatible con POSIX, en lugar de arrays se utilizan cadenas de texto separadas por espacios o los parámetros posicionales del shell ($1, $2...). Aquí presentamos el método que usa una cadena y un bucle for. Definir los valores y procesarlos secuencialmente con un bucle es una práctica común.
#!/bin/sh
# Definir como una cadena de texto separada por espacios
frutas="manzana banana cereza"
# Usar un bucle for para imprimir todos los elementos en orden
for fruta in $frutas; do
echo "¡Me gusta la $fruta!"
done
Resultado:
¡Me gusta la manzana!
¡Me gusta la banana!
¡Me gusta la cereza!
2. Sintaxis de las bifurcaciones condicionales
Las bifurcaciones condicionales del tipo "si pasa XX, haz YY" son la base de los scripts. Aquí también hay una gran diferencia.
La forma de Bash (dialecto)
En Bash se puede usar un comando de prueba más avanzado, [[ ... ]]. Es muy práctico porque permite encadenar múltiples condiciones con &&, comparar cadenas con == y hacer coincidencia de patrones.
#!/bin/bash
nombre="Taro"
edad=25
# Encadenar dos condiciones con &&
if [[ "$nombre" == "Taro" && "$edad" -gt 20 ]]; then
echo "¡Bienvenido, Taro!"
fi
Resultado:
¡Bienvenido, Taro!
La forma compatible con Dash (lenguaje estándar)
El comando de prueba compatible con POSIX es [ ... ]. Es un comando más antiguo con algunas limitaciones. Por ejemplo, la comparación de cadenas se hace con un solo =, y para múltiples condiciones se debe usar -a (AND), -o (OR) o combinar varios [ ]. Por seguridad, se recomienda combinar varios [ ].
#!/bin/sh
nombre="Taro"
edad=25
# Escribir la condición usando dos [ ]
if [ "$nombre" = "Taro" ] && [ "$edad" -gt 20 ]; then
echo "¡Bienvenido, Taro!"
fi
Resultado (el mismo):
¡Bienvenido, Taro!
3. Sustitución de cadenas de texto
También es muy común querer reemplazar un carácter específico dentro de una variable por otro.
La forma de Bash (dialecto)
En Bash, puedes sustituir cadenas fácilmente con la sintaxis ${variable/antiguo/nuevo}.
#!/bin/bash
nombre_archivo="foto_2025.jpg"
# Sustituir "jpg" por "png"
nuevo_nombre_archivo=${nombre_archivo/jpg/png}
echo $nuevo_nombre_archivo
Resultado:
foto_2025.png
La forma compatible con Dash (lenguaje estándar)
Al escribir de forma compatible con POSIX, lo habitual es combinar comandos externos como sed o awk para manipular cadenas. Aquí tienes un ejemplo con sed. Es un poco más largo, pero te da la tranquilidad de que funcionará sin problemas en cualquier entorno.
#!/bin/sh
nombre_archivo="foto_2025.jpg"
# Pasar el contenido de la variable al comando sed con echo para la sustitución
nuevo_nombre_archivo=$(echo "$nombre_archivo" | sed 's/jpg/png/')
echo "$nuevo_nombre_archivo"
Resultado (el mismo):
foto_2025.png
Conclusión: Entonces, ¿cuál deberías usar?
Hemos visto las diferencias, pero lo que realmente quieres saber es: "entonces, ¿cuál uso?". La respuesta es "depende de la situación", pero hay una pauta recomendada para principiantes.
Elección recomendada por caso de uso
-
Para tareas rápidas en la terminal 👉 ¡Usa Bash sin dudarlo!
En tu shell de uso diario, aprovecha al máximo las funciones útiles como el autocompletado y el historial. No es necesario usar una sintaxis más incómoda. -
Para scripts que se ejecutarán en un servidor o se distribuirán a otros 👉 ¡Ten muy en cuenta Dash (compatible con POSIX)!
Si el script no solo tiene que funcionar en tu entorno, la compatibilidad es lo más importante. Usa#!/bin/shy esfuérzate por escribir en el "lenguaje estándar" de POSIX. Esto aumenta enormemente las posibilidades de que tu script siga funcionando en Linux, BSD e incluso en futuros sistemas.
Consejo para principiantes
Si estás empezando a aprender a hacer scripts de shell, te recomendamos aprender desde el principio a escribir de forma compatible con POSIX usando `#!/bin/sh`. ¿Por qué? Porque el más compatible abarca al menos compatible. Un script compatible con POSIX funcionará sin problemas en Bash, pero lo contrario no es cierto. Si dominas el "lenguaje estándar" desde el principio, no tendrás problemas sin importar el entorno en el que te encuentres.
¡Cuidado! Los "dialectos" de Bash (Bashisms) que podrías usar sin darte cuenta
Es muy común escribir código pensando que está bien, y que en realidad sea un "dialecto" de Bash. Aquí te presentamos algunos de los "Bashisms" más frecuentes.
[[ ... ]]: Ya lo hemos mencionado, pero es el Bashism más representativo. Acostúmbrate a escribir las bifurcaciones condicionales con[ ... ].function mi_func { ... }: La palabra clavefunctionpara definir funciones es de Bash. La forma compatible con POSIX esmi_func() { ... }.echo -e "...": La opción-e, que interpreta secuencias de escape como\n(salto de línea), no se comporta igual en todos los shells. Usar el comandoprintfen su lugar es mucho más seguro y fiable.source ./mi_script.sh: El comandosourcepara cargar otro script también es un Bashism. La versión compatible con POSIX es. ./mi_script.sh(un punto y un espacio).
Solo con evitar estos Bashisms, la compatibilidad de tus scripts mejorará drásticamente.
Resumen: ¡Domina la comodidad de Bash y la robustez de Dash!
En este artículo, hemos explicado cómo escribir scripts de shell altamente compatibles a través de las diferencias entre Bash y Dash.
- Para el uso diario en la terminal, quédate con Bash y su gran cantidad de funciones útiles.
- Al escribir scripts, ten en cuenta Dash (compatible con POSIX) para que funcionen en cualquier entorno.
- Si tienes dudas, la mejor práctica es escribir
#!/bin/shen la primera línea de tu script y practicar la escritura en el "lenguaje estándar" de POSIX.
Si adquieres esta forma de pensar, podrás prevenir problemas de "no funciona por el entorno" y escribir scripts que sean útiles en muchas más situaciones. ¿Qué tal si empiezas hoy mismo a aspirar a crear "scripts que funcionan en cualquier lugar"?
A continuación, te recomendamos este artículo
Ejemplos de scripts en Dash (sentencias if, bucles, funciones simples)