Cómo usar subshells Bash dentro de declaraciones

Cómo usar subshells Bash dentro de declaraciones

Si alguna vez ha usado subshells de Bash (ps), ya sabes cuán flexibles pueden ser las subshells. Solo se necesitan unos pocos personajes para comenzar una subshell para procesar cualquier cosa necesaria, en línea a otra declaración. El número de casos de uso posibles es prácticamente ilimitado.

También podemos usar subshells Bash en el interior si declaraciones, en línea con la declaración. Hacerlo le da al usuario y al desarrollador mucha flexibilidad adicional cuando se trata de escribir bash si declaraciones.

Si aún no está familiarizado (o desea obtener más información sobre) Bash si las declaraciones, consulte nuestra bash si las declaraciones: si elif lo más entonces FI Artículo.

En este tutorial aprenderás:

  • Cómo incorporar subshells Bash en el interior si declaraciones
  • Métodos avanzados para incorporar subshells bash en línea con otros comandos
  • Ejemplos que demuestran el uso de subshells bash en si declaraciones
Cómo usar subshells Bash dentro de declaraciones

Requisitos y convenciones de software utilizados

Requisitos de software y convenciones de línea de comandos de Linux
Categoría Requisitos, convenciones o versión de software utilizada
Sistema Independiente de la distribución de Linux
Software Línea de comando bash, sistema basado en Linux
Otro Cualquier utilidad que no esté incluida en el shell bash de forma predeterminada se puede instalar utilizando sudo apt-get instalación de utilidad de utilidad (o yum instalación para sistemas basados ​​en redhat)
Convenciones # - requiere que los comandos de Linux se ejecuten con privilegios raíz directamente como un usuario raíz o mediante el uso de sudo dominio
$-Requiere que los comandos de Linux se ejecuten como un usuario regular no privilegiado

Ejemplo 1: Empezando simple

Veamos un ejemplo simple para comenzar. Tenga en cuenta que estas declaraciones, mientras se ejecutan aquí en la línea de comandos, también se pueden incorporar en un script de shell bash (un archivo de texto sin formato, preferiblemente con un .mierda extensión, y marcada como ejecutable utilizando el chmod +x myscript.mierda Comando - donde myscript.mierda es un ejemplo de nombre de archivo). También presentamos un error para hacer las cosas más interesantes.

$ if ["test" == "$ (echo 'test')"]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; partidos de FI! $ if ["test" == "$ (echo 'incorrecto')"]; luego hacer eco de partidos!'; else 'no coincide!'; FI no coincide!: comando no encontrado $ 


En el primer comando, usamos una prueba simple (if ["some_text" == "some_other_text"]; entonces… ) para verificar la igualdad entre dos cuerdas. Para la segunda cadena, hemos comenzado una subshell de Bash (ps) para emitir la palabra prueba. El resultado es que prueba partidos prueba Y así los comandos después del entonces Se ejecutará la cláusula, en este caso partidos de eco!' se ejecuta y Partidos! huellas dactilares.

En el segundo comando, cambiamos el comando ECHO a una coincidencia de texto incorrecta al dejar que el echo/salida subshell incorrecto ($ (echo 'incorrecto')). Recibimos un error de aspecto extraño. Mira de cerca, ¿puedes detectar el error?? Compare también el segundo comando con el primero.

El problema es que en nuestro segundo comando, el demás cláusula (que se ejecuta cuando falla la coincidencia de igualdad, yo.mi. 'qué demás hacer cuando la declaración if no era verdadera) falla un eco dominio. Mientras que puede leer con fluidez (si ... entonces eco ... de lo contrario ...) El comando es incorrecto, ya que requiere un eco adicional. El resultado es que el shell bash intenta ejecutar No coincide! Como comando literal.

Solucionemos esto!

$ if ["test" == "$ (echo 'incorrecto')"]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; FI no coincide! 

Mucho mejor. Y podemos ver nuestra subshell, es eco, y el completo si declaración ejecutando correctamente. Genial, vamos un poco más profundos.

Ejemplo 2: Declaración de subshell de un poco más compleja si

$ Var1 = "ABC"; if [["$ (echo" $ var1 ")" == * "b" *]]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; partidos de FI! $ Var1 = "adc"; if [["$ (echo" $ var1 ")" == * "b" *]]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; FI no coincide! 

Aquí establecemos una variable Varilla a cualquiera a B C o ADC y siguiente salida esta variable, nuevamente usando una subshell, contra la presencia de b en la cuerda. Tenga en cuenta que el asterisco original (*) prefijo al "b" La cláusula de comparación indica cualquier cosa antes de esta cadena y el sufijo asterisco (*) Del mismo modo cualquier cosa después de esta cadena. Podemos ver como b fue encontrado en el primero a B C cadena, pero no en el segundo comando/cadena donde ADC se usó como una cadena de comparación.

Tenga en cuenta también cómo usamos [[...]] corchetes para el si Declaración esta vez. Esto no está relacionado con el uso de subshells, y es simplemente un estándar de escritura más nuevo si declaraciones que se pueden usar para casos de uso adicionales u otros […] sintaxis. Lo requerimos aquí para hacer el especial b coincidencia que estamos intentando, usando el asterisco (*) prefijo y sufijo al "b" Comparar cláusula.

en un si declaración con soltero […] Brackets Esto fallaría:

$ if ["ABC" == * "B" *]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; FI no coincide! $ if [["ABC" == * "B" *]]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; partidos de FI! 

Como el si [… ] La sintaxis no reconoce el asterisco (*) prefijo y sufijo al "b" Compare la cláusula, y uno necesita usar [[...]] entre paréntesis en su lugar.

Otra cosa a tener en cuenta es que esta vez usamos cotizaciones dobles (") Dentro de la subshell (en lugar de las citas individuales como en el primer ejemplo): cuando uno inicia una subshell, tal uso de citas dobles no solo se permite, sino que puedo recomendarlo para diversos casos de usos. Es útil en algunas situaciones en las que se está realizando un montón de análisis complejo y es necesaria una combinación de citas individuales y dobles. Las cotizaciones dobles no terminarán las citas iniciadas antes y fuera de la subshell.

Tenga en cuenta que con la mayoría de los ejemplos anteriores, uno podría haber dejado la subshell y hacer una comparación simple directamente con la variable, I, i.mi.:

$ Var1 = "ABC"; if [["$ var1" == * "b" *]]; luego hacer eco de partidos!'; de lo contrario echo 'no coincide!'; partidos de FI! 

Sin embargo, elegimos introducir subshells con eco (efectivamente una operación nula, yo.mi. efectivamente lo mismo que solo usar la variable o el texto en cuestión), ya que resaltaría que 1) las subshells funcionan de manera efectiva, y 2) que pueden usarse desde adentro si declaraciones.

Ejemplo 3: Declaraciones de subshell IF avanzadas si

No necesitamos restringir nuestro uso de subshell en el interior si declaraciones a un solo comando, ni al uso de eco solo. Hagamos una pequeña configuración:

$ touch a $ ls -color = nunca ./a | WC -L 1 


Creamos un archivo llamado a, y contó el número de líneas (usando WC -L, una herramienta de conteo que puede contar el número de líneas utilizando el -l opción). También nos aseguramos de presentar el --color = nunca opción para LS Para evitar problemas de análisis cuando se usa la codificación de color terminal.

A continuación, trabajemos estas declaraciones directamente en si declaraciones:

$ if [-z "$ (ls -color = nunca ./a | wc -l) "]; luego echo" salida de directorio vacío!"; fi $ if [" $ (ls -color = nunca ./a | wc -l) "-eq 1]; luego echo" exactamente un archivo encontrado!"; Fi exactamente un archivo encontrado! ps 

Aquí usamos lo mismo ls ... wc -l código dos veces directamente desde dentro de un si declaración. La primera si declaración, que usa -z verifica si el texto entre cotizaciones (la primera opción para el -z If-Instrucción) está vacío. No es como el LS El comando producirá alguna salida en este caso, dado que creamos el archivo a.

En el segundo comando, en realidad probamos si la salida de nuestro ls ... wc -l El comando es igual a 1 usando el -ecualización Opción de prueba en el si declaración. ecualización representa igual a. Tenga en cuenta que -ecualización (y es reverso -nordeste ser no igual a) solo se puede usar para números. Para cadenas basadas en texto, use == (igual) y != (no igual) en su lugar.

La salida de comando (Exactamente un archivo encontrado!) es correcto, y nuestro si Declaración con un subshell de múltiples múltiples múltiples funciona bien!

También de interés para notar que el primer valor compare en el segundo si declaración (yo.mi. $ (ls -color = nunca ./a | wc -l) con salida 1) es numérico. Entonces, ¿por qué hemos usado dos citas dobles ("...") alrededor de la declaración de subshell? Esto no tiene nada que ver con las subshells, y todo con cómo si Funciona en Bash, y uno puede no saber este truco o taquigrafía todavía; Considere esto:

$ V = "1 1" $ if [$ V -eq 0]; Entonces se eco '0'; fi bash: [: demasiados argumentos $ if ["$ v" -eq 0]; Entonces se eco '0'; fi bash: [: 1 1: expresión entera esperada $ v = 0 $ if ["$ v" -eq 0]; Entonces se eco '0'; Fi 0 

En otras palabras, usar citas dobles es una forma ligeramente más segura de programación si declaraciones, incluso si la condición es una condición numérica. Protege contra las cadenas más complejas que se interpretan como elementos individuales en lugar de un solo valor, y devuelve un mensaje de error correcto (Expresión entera esperada), en lugar de los más ambiguos Bash: [: Demasiados argumentos error.

Tampoco le importa a Bash que esté comparando lo que parece ser una cadena de texto (como lo indica "...") con un valor numérico; funciona, siempre que el número sea numérico. Y si no es así, aún proporcionará un mejor mensaje de error que indica que la cadena no es numérica, como se ve. En resumen, es mejor citar siempre su subshell, texto o variable con citas dobles, incluso al comparar elementos numéricos. Para demostrar que esto funciona bien, considere:

$ if ["1" -eq "1"]; Entonces se eco 'y'; fi y $ if ["1" -eq "0"]; Entonces se eco 'y'; fi $ 

Conclusión

En este artículo, miramos la incorporación de subshells de Bash en el interior si declaraciones. Exploramos varios ejemplos, desde fácil hasta avanzado, sobre cómo podemos usar subshells de Bash en el interior si declaraciones. También nos sumergimos un poco en el uso de cotizaciones dobles al comparar, incluso al comparar campos numéricos. Uso de subshells dentro de otros comandos, y en este caso si declaraciones es una forma poderosa de expandir sus habilidades de secuencia de comandos. Disfrutar!

Tutoriales de Linux relacionados:

  • Subshells de Linux avanzados con ejemplos
  • Subshells de Linux para principiantes con ejemplos
  • BASH IF Declaraciones: si, elif, de lo contrario, entonces, FI
  • Mastering Bash Script Loops
  • Tutorial de depuración de GDB para principiantes
  • Scripting de bash y gestión de procesos multiprocesos en el ..
  • Bash Loops con ejemplos
  • Cosas que hacer después de instalar Ubuntu 20.04 fossa focal Linux
  • Una introducción a la automatización, herramientas y técnicas de Linux
  • Variables de Bash especiales con ejemplos