test, [, and [[ (2020)
Los programadores de shell sopesan los compromisos entre el estándar POSIX `[ / test` y `[[` específico de Bash para condicionales, destacando cómo las reglas de sintaxis sutiles, las trampas de las comillas y las rarezas de la lógica booleana pueden introducir errores fácilmente. Muchos abogan por ceñirse a `sh` portátil y compatible con Bourne cuando los scripts deben ejecutarse en sistemas diversos o restringidos (por ejemplo, BSD, sistemas embebidos, imágenes Docker mínimas), mientras que otros prefieren las características de Bash, zsh o ksh por comodidad en entornos controlados. La conversación se amplía hacia si los scripts de shell complejos deberían reemplazarse por lenguajes “reales” como Python o Perl, el papel de herramientas como ShellCheck y `set -euo pipefail`, y cómo equilibrar la portabilidad a largo plazo con la productividad del desarrollador.
Elección de shell y portabilidad
- Gran división entre “usa Bash/[[ y listo” y “apunta a POSIX sh”.
- Lado pro-Bash:
[[es más claro y potente; muchos entornos que controlan tienen bash, zsh o ksh de todos modos. Instalar bash se ve como de poco esfuerzo en muchos contextos. - Lado de la portabilidad: bash no siempre está presente (BSD, sistemas embebidos, imágenes Docker mínimas, configuraciones solo con busybox, máquinas de clientes bloqueadas, macOS con bash antiguo).
- Escribir Bourne/POSIX sh se describe como parte de la madurez profesional cuando los scripts se ejecutan en sistemas desconocidos o heredados.
- Algunos sostienen que la portabilidad tiene un costo y no debería ser un objetivo universal; para scripts internos está bien apoyarse en bashisms.
[, test, y [[
[,testson POSIX y suelen ser binarios o builtins;[[es específico del shell (bash, zsh, ksh, etc.).- Varios prefieren
testsobre[para reforzar que es un comando, no sintaxis; la]de cierre de[y la “sintaxis” parecida se ven como trucos engañosos. - Otros dicen que
[[es preferible cuando ya has apostado por Bash, por su semántica más segura (por ejemplo, regex, coincidencia de patrones, menos problemas de comillas). - Algunos insisten en usar solo características POSIX incluso cuando los shells soportan
[[; otros dicen que eso es una adoración innecesaria de la portabilidad.
Errores comunes y técnicas
- La mayor trampa: variables sin comillas con
test/[(valores vacíos o con espacios, comportamiento de un solo argumento). Consejo repetido: “cita tus variables” y usa herramientas como ShellCheck yset -euo pipefail. - Usar
&&/||como abreviatura deifes popular, pero tiene semánticas de fallo diferentes cuando falla el comando después de&&. -a/-odentro detestse señalan como obsoletos; se prefiere encadenar pruebas separadas con&&/||.- La lógica booleana es incómoda: no hay un tipo booleano real; las soluciones usan códigos de salida o 0/1 numéricos.
Cuándo usar shell frente a otro lenguaje
- Varios sostienen que la lógica compleja debería pasar a un lenguaje “real” (Python, Perl, Node/zx, etc.); shell es mejor para pegamento, orquestación y pruebas de integración.
- Otros defienden shell como un lenguaje “real” si se usa con disciplina, pero aun así no empezarían proyectos grandes en él.
Estándares, GNUismos y rarezas del ecosistema
- Debate sobre ceñirse a POSIX frente a explotar extensiones GNU/Bash (
pipefail, banderas GNUgrep/sed, etc.). - POSIX se ve como valioso para la interoperabilidad, pero también como rezagado respecto a las necesidades del mundo real.
- Varias notas laterales: dash como
/bin/shen Debian/Ubuntu, macOS BSD frente a herramientas GNU, el trato especial de autoconf a[], comportamientos extraños de$_, y disposiciones de busybox con symlink frente a hardlink.