Shellcheck encuentra errores en tus scripts de shell

ShellCheck, una herramienta de análisis estático para scripts de shell, es elogiada por descubrir rápidamente errores sutiles y patrones peligrosos en todo, desde scripts de mantenimiento heredados hasta canalizaciones modernas de CI. Quienes comentan describen su integración en hooks de pre-commit y wrappers para GitLab CI, al tiempo que señalan herramientas complementarias como linters para Dockerfile y servidores de lenguaje para bash. Al mismo tiempo, muchos sostienen que la automatización compleja debería salir por completo del shell y pasar a lenguajes como Python, Haskell o Swift, usando shell solo como pegamento ligero alrededor de herramientas de línea de comandos y confiando en linters para mantener segura incluso esa utilización tan limitada.

Sentimiento general sobre ShellCheck

  • Ampliamente elogiado como una herramienta “imprescindible”; detecta errores sutiles incluso para usuarios de shell muy experimentados.
  • Especialmente valorado en bases de scripts de shell grandes o heredadas y en canalizaciones de CI.
  • Algunos lo consideran lo bastante esencial como para imponer “no se ejecuta ningún script si ShellCheck falla”, mediante wrappers o shebangs estrictos.

Integración en CI / flujo de trabajo de desarrollo

  • Patrón común: ejecutar ShellCheck mediante hooks de pre-commit y trabajos de CI.
  • Punto problemático: el shell incrustado en otros archivos (por ejemplo, YAML de GitLab CI, GitHub Actions, Dockerfiles, Justfiles) es más difícil de analizar; varios usuarios construyeron wrappers o hooks para extraer y pasar lint a estas secciones.
  • Algunos proponen poner todo el shell no trivial en scripts separados llamados desde CI, tanto para el linting como para la portabilidad.
  • Alternativas como Dagger buscan codificar canalizaciones de CI/CD en lenguajes de programación reales; hay debate sobre su madurez y los detalles de integración con GitLab.

Shell frente a otros lenguajes

  • Fuerte desacuerdo:
    • Un bando: evitar shell siempre que sea posible; usar Python, Ruby, Go, Haskell, Swift, etc., especialmente para lógica compleja o código sensible a la seguridad.
    • Otro bando: shell es ideal para pequeños scripts de “pegamento” y tareas de CI; no hay una forma más fácil de componer herramientas CLI.
  • Python suele proponerse como la principal alternativa, pero la gente se queja del empaquetado, la distribución y la sobrecarga en tiempo de ejecución.
  • Algunos informan migraciones exitosas de Bash a Haskell (Turtle/Shh) o Swift (Shwift), obteniendo seguridad de tipos y estructura.

Limitaciones y casos límite

  • ShellCheck tiene dificultades con:
    • source/imports entre varios archivos.
    • Zsh (se eliminó el soporte; forzar --shell=bash solo funciona parcialmente).
    • Algunos problemas de seguridad, por ejemplo la inyección en expansión aritmética, salvo que se configure de forma más estricta.
    • Particularidades de versiones de Bash (set -u, arrays vacíos, arrays asociativos, el comportamiento de [[ -v ... ]] difiere entre versiones).
  • Los usuarios personalizan con frecuencia las reglas (por ejemplo, desactivar comprobaciones de estilo para ${var} o el entrecomillado obligatorio).

Buenas prácticas de Shell comentadas

  • Recomendaciones frecuentes: set -u, -e, -o pipefail, -n para simulación, y uso liberal de trap para limpieza.
  • Debate sobre poner opciones en el shebang frente a set (preocupaciones de portabilidad y del estilo de invocación).
  • Algunos promueven un wrapper de “modo estricto” o herramientas de corrección automática como shellharden para imponer scripts más seguros y consistentes.