Bash es un lenguaje de codificación y shell ideal, lo que le posibilita crear scripts de automatización de alta gama. En esta segunda parte de la serie, veremos la densidad de codificación, los comentarios en línea y las comillas correctas de las variables usando comillas simples o dobles.
Conceptos básicos de automatización de bash y secuencias de comandos
Si aún no lo ha hecho, y recién está comenzando en Bash, lea nuestro post Bash Automation and Scripting Basics Part 1. Este es el segundo post de nuestra serie de tres partes sobre los conceptos básicos de automatización y scripts de Bash. En el post de hoy veremos, entre otros temas, la densidad de codificación Bash y su conexión con las preferencias del desarrollador. Además veremos los comentarios en línea en vinculación con esto.
Una vez que empezamos a crear pequeños scripts, exploramos variables y trabajamos con cadenas de texto, rápidamente nos damos cuenta de que puede haber una diferencia conceptual entre comillas simples y dobles. La hay, y en el segundo tema a continuación nos sumergiremos en esto.
Densidad y concisión de la codificación Bash
El lenguaje de codificación Bash puede ser muy denso y conciso, pero además puede ser espacioso y detallado. Depende en gran medida de las preferencias del desarrollador.
A modo de ejemplo, el siguiente código Bash:
true || echo 'untrue'
Que se puede leer como No haga nada y hágalo con éxito (código de salida 0), y si eso falla (puede leer el modismo Bash ||
como OR) muestra el texto ‘falso’, además se puede escribir como:
if [ ! true ]; then echo 'untrue' fi
Lo que hace que el código sea un poco distinto, pero simplemente hace lo mismo.
Esto a su vez se puede leer como Si es verdad no es (significado por el !
idiom) verdadero, después muestra el texto ‘falso’.
Ambos mini-scripts dan como consecuencia la misma salida vacía, como cierto no es falso.
La multitud de comandos y herramientas disponibles (o instalables) desde y en la línea de comandos amplían aún más el factible desplazamiento entre scripts altamente legibles y código denso, conciso y difícil de comprender.
Mientras que los ejemplos anteriores son breves y relativamente fáciles de comprender, cuando crea una línea larga (una definición que se utiliza a menudo entre los desarrolladores de Bash para indicar un fragmento de código, que consta de varios comandos, escritos en una sola línea) empleando muchos de esos comandos , en lugar de poner lo mismo en un guión más detallado, la diferencia se torna más clara. Considerar:
V="$(sleep 2 & fg; echo -n '1' | sed 's|[0-9]|a|')" && echo "${V}" | sed 's|[a-z]|2|g' || echo 'fail'
Este es un script típico de Bash de una sola línea que utiliza los comandos sleep
, fg
, echo
, y sed
así como varios modismos de Bash y expresiones regulares para dormir simplemente 2 segundos, generar texto y transformar este texto usando expresiones regulares. El script además verifica regularmente las condiciones / resultados de comandos anteriores a través de el uso de modismos Bash ||
(si no tiene éxito, haga lo siguiente) y &&
(si tiene éxito, haga lo siguiente)
Traduje esto, con una funcionalidad de coincidencia aproximada, a un script más completo, con algunas modificaciones. A modo de ejemplo, cambiamos nuestro fg
(trae el sleep
comando colocado en segundo plano de nuevo en primer plano, y espere a que termine como procesos normales sin segundo plano) para wait
que esperará el PID del sueño (iniciado por eval
y capturado usando el modismo Bash $!
) para terminar.
#!/bin/bash CMD="sleep 2" eval ${CMD} & wait $! EXIT_CODE=${?} V="$(echo -e "${CMD}n1" | sed 's|[0-9]|a|')" if [ ${EXIT_CODE} -eq 0 ]; then echo "${V}" | sed 's|[a-z]|2|g' EXIT_CODE=${?} if [ ${EXIT_CODE} -ne 0 ]; then echo 'fail' fi fi
¡Qué diferencia! Y esto es solo uno desarrollador escribiéndolo en su camino. El código Bash escrito por otros tiende a ser algo difícil de leer, y esa dificultad aumenta rápidamente con la densidad y la concisión. Aún así, un desarrollador de nivel experto en Bash comprenderá rápidamente inclusive el código muy denso y conciso escrito por otros, con algunas excepciones, a modo de ejemplo, las expresiones regulares.
Para obtener más información acerca de cómo escribir expresiones regulares, eche un vistazo a Cómo modificar texto usando expresiones regulares con sed Stream Editor.
A partir de estos ejemplos, queda claro que su kilometraje variará con el tiempo. A pesar de esto, en general, se recomienda la facilidad de uso del programador (escribiendo código altamente legible) siempre que comience a desarrollar scripts Bash.
Si tiene que crear un código denso y conciso, puede proporcionar muchos comentarios en línea. Una línea prefijada por un #
se considera una línea de comentario / observación, y el símbolo #
inclusive se puede utilizar hacia el final de una línea después de cualquier comando ejecutable, para publicar un comentario de sufijo que explique el comando, declaración condicional, etc. A modo de ejemplo:
# This code will sleep one second, twice sleep 1 # First sleep sleep 1 # Second sleep
¿Cotizaciones simples o cotizaciones dobles?
En Bash, texto entre comillas simples ('
) son tomados como texto literal por el intérprete de Bash, mientras que el texto entre comillas dobles ("
) es interpretado (analizado) por el intérprete de Bash. Mientras que la diferencia en cómo funcionan las cosas puede no ser clara de inmediato a partir de esta definición, el siguiente ejemplo nos muestra lo que sucede cuando intercambiamos '
por "
y viceversa:
echo ' $(echo "Hello world") ' echo " $(echo 'Hello world') "
En el primer ejemplo, el texto $(echo "Hello world")
se ve como texto literal, por lo que la salida es simplemente $(echo "Hello world")
. A pesar de esto, para el segundo ejemplo, la salida es Hello world
.
El intérprete de Bash analizó el texto entre comillas dobles para ver si encontraba algún lenguaje de Bash especial sobre el que actuar. Uno de esos modismos se encontró en $( ... )
que simplemente inicia una subcapa y ejecuta lo que esté presente entre el ( ... )
modismos. Piense en ello como un shell dentro de un shell, un subshell, que ejecuta todo lo que le pasa como un comando absolutamente nuevo. La salida de cualquier comando o comandos de este tipo se devuelve al shell de nivel superior y se inserta en el lugar exacto donde se inició el subshell.
Por eso, nuestra subcapa ejecutó echo 'Hello world'
de los cuales la salida es Hello world
. Una vez realizado esto, la subcapa terminaba y el texto Hello world
fue insertado en lugar del $( ... )
invocación de subcapa (piense en ello como todos los $( ... )
el código está siendo reemplazado por cualquier salida generada por la subcapa.
El resultado, para el shell superior, es el siguiente comando: echo " Hello world "
, de los cuales la salida es Hello world
como vimos.
Tenga en cuenta que cambiamos las comillas dobles dentro de la subcapa a comillas simples. ¡Esto no es necesario! Uno esperaría ver un error de análisis cuando un comando toma la sintaxis de echo " ... " ... " ... "
, en el sentido de que las segundas comillas dobles terminarían con la primera, seguidas de más pruebas y, por eso, provocarían un error. A pesar de esto, este no es el caso.
Y esto no se debe a que Bash sea flexible con cadenas de comillas múltiples (acepta echo 'test'"More test"'test'
felizmente, a modo de ejemplo), sino debido a que la subcapa es una carcasa en sí misma y, por eso, se pueden utilizar comillas dobles, nuevamente, dentro de la subcapa. Probemos esto con un ejemplo adicional:
echo "$(echo "$(echo "more double quotes")")"
Esto funcionará bien y producirá la salida more double quotes
. Las dos subcapas anidadas (que se ejecutan dentro de la shell principal desde la que está ejecutando esto) aceptan, a su vez, comillas dobles y no se generan errores, inclusive si se anidan varias comillas dobles en el comando general de una sola línea. Esto muestra parte del poder de programación de Bash.
En resumen
Habiendo explorado la densidad de codificación, nos damos cuenta del valor de escribir código altamente legible. Sin embargo, si tenemos que hacer un código denso y conciso, podemos agregar muchos comentarios en línea usando #
para facilitar la legibilidad. Observamos las comillas simples y dobles y cómo su funcionalidad difiere sustancialmente.
Además analizamos brevemente los comentarios en línea en los scripts, así como la funcionalidad de la subcapa cuando se ejecuta desde una cadena entre comillas dobles. En conclusión, vimos cómo una subcapa puede utilizar otro conjunto de comillas dobles sin afectar de ninguna manera las comillas dobles utilizadas en un nivel superior.
En Bash Automation and Scripting Basics (Parte 3), analizamos la depuración de scripts y más. ¡disfrutar!