Expansión de la expansión de shell bash, expansión de parámetros y más

Expansión de la expansión de shell bash, expansión de parámetros y más
En este artículo cubriremos todas las características básicas de la expansión de shell de Bash. Algunas de las expansiones más complejas e interesantes son la expansión de los aparatos ortopédicos y la expansión de los parámetros que tienen muchas características y opciones que son potentes pero que solo se dominan con el tiempo por los programadores de BASH y Linux DevOps Folks. La división de palabras también es bastante interesante y en algún momento se pasa por alto. El nombre de archivo, la expansión aritmética y la sustitución variable son bien conocidos. Cubriremos numerosos temas y mostraremos ejemplos del comando y las sintaxis más útiles para cada sintaxis. Entonces empecemos.
  • Ambiente
  • Sustitución de comandos
  • Sustitución de procesos
  • Sustitución variable
  • Expansión de la abrazadera
  • Expansión de parámetros
  • Parámetros posicionales
  • Expansión de Tilde
  • Sustitución aritmética
  • División de palabras
  • Expansión del nombre de archivo
  • Conclusión

Ambiente

Para probar todas las funciones de expansiones de shell bash, debemos asegurarnos de que estamos ejecutando una versión reciente de bash. A continuación se muestra la información del sistema para este artículo. Las pruebas en este artículo se ejecutan en Ubuntu 19.10 como se muestra a continuación.

$ uname -a
Instancia de Linux-1 5.3.0-1014-GCP #15-UBUNTU SMP martes 3 04:14:57
UTC 2020 x86_64 x86_64 x86_64 gnu/linux

La versión bash para estas pruebas es bash versión 5, que es bastante reciente. Las versiones más antiguas de Bash les faltan un montón de características.

$ Bash -Versión
GNU Bash, versión 5.0.3 (1) -lelase (x86_64-pc-linux-gnu)
Copyright (c) 2019 Free Software Foundation, Inc.
Licencia GPLV3+: GNU GPL versión 3 o posterior

Sustitución de comandos

La sustitución del comando permite la ejecución de uno o múltiples comandos y capturando salidas y acciones de esos comandos e incluyendo en otro comando, todo en una línea o menos líneas que ejecutar todos los comandos por separado. La sustitución del comando tiene dos sintaxis; La sintaxis más popular es la sintaxis de retroceso donde el comando que se ejecutará está encerrado en dos retrocesos o backticks. La otra sintaxis, que es igualmente potente, los comandos de encierra en la sintaxis de $ () y la salida se puede usar a partir de esa nueva expansión. Veamos una serie de ejemplos de sustitución de comandos a continuación.

Sustitución de comando simple usando la sintaxis $ () para ejecutar el comando de fecha.

$ echo $ (fecha)
Miércoles 18 de marzo 01:42:46 UTC 2020

Sustitución de comando simple usando sintaxis de retroceso para ejecutar el comando de fecha.

$ echo 'fecha'
Miércoles 18 de marzo 01:43:17 UTC 2020

El uso del operador Stdin al comienzo de la sintaxis de sustitución de comando es una forma elegante de leer el texto de un archivo en una variable y usarlo en un comando en el shell como se muestra a continuación.

$ echo "Hello World"> Mytext
$ Echo $ (< mytext)
Hola Mundo

Lea un archivo en una variable que se utilizará en un comando utilizando el comando CAT y la sustitución del comando.

$ echo "Hello World"> Mytext
$ Echo $ (Cat Mytext)
Hola Mundo

Igual que el anterior, lea un archivo y úselo en la sustitución de comandos usando el comando Backticks y CAT.

$ echo "Hello World"> Mytext
$ Echo 'Cat Mytext'
Hola Mundo

Combine la sustitución de comandos integrados con otra sustitución de comando usando $ () y retroceso juntos

$ echo 'echo $ (fecha) | corte -d "" -f 1'> myfile
$ Cat MyFile
Casarse

Sustitución de comandos integrados dentro de otro usando dos operaciones de sintaxis de $ ()

$ echo "hoy es $ (echo $ (fecha) | cortado -d" "-f 1)"> myfile
$ Cat MyFile
Hoy es miércoles

Use la salida de un comando como argumentos en otro comando, con la sintaxis de retroceso. Obtendremos una lista de archivos ejecutando CAT que contiene un archivo por línea y luego lo pasaremos al comando RM que eliminará cada archivo

$ touch uno; tocar dos
$ echo one> myfiles; echo dos >> myfiles
$ rm 'gato myfiles'

Igual que el anterior pero con $ () sintaxis, pase la salida del comando de CAT en el comando RM para eliminar archivos.

$ touch uno; tocar dos
$ echo one> myfiles; echo dos >> myfiles
$ RM $ (Cat MyFiles)

Almacene la salida de un comando CAT en una variable y luego pase a través de la variable para que pueda ver más claramente lo que está sucediendo.

$ touch uno; tocar dos
$ echo one> myfiles; echo dos >> myfiles
$ Myfiles = $ (gato myfiles)
$ para f en $ myfiles; hacer eco $ f; RM $ F; hecho
uno
dos

Igual que el anterior, pero use la sintaxis de Backticks para ejecutar el comando CAT y almacenar la salida en una variable y luego recorrer los archivos int la variable.

$ touch uno; tocar dos
$ echo one> myfiles; echo dos >> myfiles
$ Myfiles = 'gato myfiles'
$ para f en $ myfiles; hacer eco $ f; RM $ F; hecho
uno
dos

Use la sustitución del comando con el operador STDIN para leer un archivo línea por línea en una variable y luego recorrer la variable después de la palabra de palabras

$ touch uno; tocar dos
$ echo one> myfiles; echo dos >> myfiles
$ Myfiles = $ (< myfiles)
$ para f en $ myfiles; hacer eco $ f; RM $ F; hecho
uno
dos

Sustitución de procesos

La sustitución del proceso es una característica documentada de BASH; Es bastante críptico en mi opinión. De hecho, no he encontrado muchos buenos casos de uso para recomendarlo. Un ejemplo se incluye aquí para completar el lugar donde utilizamos la sustitución del proceso para obtener la salida de un comando y luego usarlo otro comando. Imprimiremos la lista de archivos en orden inverso con el comando de clasificación en este ejemplo después de obtener archivos del comando ls.

$ touch one.TXT; tocar dos.TXT; tocar tres.TXT
$ sort -r <(ls *txt)
dos.TXT
tres.TXT
uno.TXT

Sustitución variable

La sustitución variable es lo que puede considerar el uso básico de las variables y sustituir el valor de la variable cuando se hace referencia. Es bastante intuitivo, algunos ejemplos se proporcionan a continuación.

Asignación y uso de variables simples donde colocamos una cadena en la variable x y luego la imprimimos en stdout

$ X = 12345
$ echo $ x
12345

Compruebe si se le asigna una variable algo o nula, en este caso se asigna para que la imprimamos en stdout

$ X = 12345
$ if [-z "$ x"]; Entonces echo "x es nulo"; más eco $ x; FI
12345

Compruebe si se le asigna una variable algo o nula, en este caso no está configurado para que imprimamos "es nulo" en lugar del valor.

$ unset x
$ if [-z "$ x"]; Entonces echo "x es nulo"; más eco $ x; FI
X es nulo

Expansión de la abrazadera

La expansión de Brace es una característica súper poderosa de Bash que le permite escribir scripts y comandos más compactos. Tiene muchas características y opciones diferentes que se describen a continuación. Dentro de los aparatos ortopédicos, su sintaxis se interpreta en una sintaxis más detallada, dependiendo de cuando ingrese a los aparatos ortopédicos. Veamos una serie de ejemplos para la expansión de Brace.

Se ejecuta cada versión de los elementos de la lista en los aparatos ortopédicos. Entonces pasamos de un comando echo e imprimimos 3 versiones de la palabra a continuación separadas por espacios.

$ echo a, m, p _warehouse
A_WAREHOUSE M_WAREHOUSE P_WAREHOUSE

Las expresiones en la expansión causan ejecución varias veces. Para demostrar esto, usamos el comando de fecha y sueño para validar que el comando de fecha se ejecuta una vez para cada iteración del patrón en la expansión de los aparatos ortopédicos.

$ echo a, m, p _ $ (fecha; dormir 1)
a_sun 22 de marzo 18:56:45 UTC 2020 M_SUN 22 de marzo 18:56:46 UTC
2020 p_sun 22 de marzo 18:56:47 UTC 2020

Las expansiones que usan números con ... causarán que los números secuenciales se amplíen en una secuencia numérica

$ echo 1 ... 8 _Warehouse
1_Warehouse 2_warehouse 3_warehouse 4_warehouse 5_warehouse 6_warehouse 7_warehouse
8_Warehouse

Expansión de abrazadera de orden inverso con secuencia de números

$ echo 8 ... 1 _Warehouse
8_Warehouse 7_Warehouse 6_Warehouse 5_warehouse 4_warehouse 3_warehouse 2_warehouse
1_warehouse

Uso de un valor de incremento opcional para especificar los incrementos numéricos de la expansión de los aparatos ortopédicos

$ echo 1 ... 9 ... 3 _Warehouse
1_Warehouse 4_warehouse 7_warehouse

La expansión de la abrazadera lexicográfica iterará a través de letras en el alfabeto en el orden del lugar

$ echo a ... e _warehouse
A_WAREHOUSE B_WAREHOUSE C_WAREHOUSE D_WAREHOUSE E_WAREHOUSE

Expansión de la abrazadera lexicográfica de orden inverso

$ echo e ... a _warehouse
e_warehouse d_warehouse c_warehouse b_warehouse a_warehouse

La expansión lexicográfica de la parrilla con incremento especificado se iterará a través de una lista de caracteres desde el principio hasta el punto final, pero omita los caracteres de acuerdo con el valor de incremento

$ echo a ... z ... 5 _Warehouse
A_WAREHOUSE F_WAREHOUSE K_WAREHOUSE P_WAREHOUSE U_WAREOSE Z_WAREHOUSE

Expansión de aparato ortopédico multiplicativo con 2 expansiones de aparato ortopédico en un solo comando

$ echo a ... e 1 ... 5 _warehouse
A1_Warehouse A2_Warehouse A3_Warehouse A4_Warehouse A5_Warehouse B1_Warehouse
B2_Warehouse B3_Warehouse B4_Warehouse B5_Warehouse C1_Warehouse C2_Warehouse
C3_Warehouse C4_Warehouse C5_Warehouse D1_Warehouse D2_Warehouse D3_Warehouse
D4_Warehouse D5_Warehouse E1_Warehouse E2_Warehouse E3_Warehouse E4_Warehouse
e5_warehouse

Expansión de aparato ortopédico para usar la misma raíz dos veces en un comando. Esto crea un foo.Archivo TGZ Tar desde un directorio con el nombre de Foo. Es una sintaxis útil donde la usas dentro de otro bucle y quieres asumir que la base de la palabra se usa varias veces. Este ejemplo lo muestra con alquitrán, pero también se puede usar con MV y CP según este ejemplo.

$ mkdir foo
$ touch foo/foo a ... e
$ tar czvf foo .tgz,
foo/
foo/foob
foo/fooc
foo/fooa
foo/comida
foo/fooe

Expansión de parámetros

La expansión de los parámetros también es una buena sintaxis compacta con muchas capacidades, como: Permitir los scripts establecer valores predeterminados para variables u opciones no establecidas, operaciones de subcadena de cadena, buscar y reemplazar sustituciones y otros casos de uso. Los ejemplos están a continuación.
Verifique si hay nulo y use el parámetro si no es nulo o el valor predeterminado. En este caso, X no es nulo, por lo que se utilizará

$ X = 1
$ echo $ x: -2
1

Verifique si hay nulo y use el parámetro si no es nulo o el valor predeterminado. En este caso X es nulo, por lo que se utilizará el valor predeterminado

$ unset x
$ echo $ x: -2
2

Compruebe si la variable es nula y se establece y hecha eco si es nula. X se asigna 2 e impresa $ x. Esto puede establecer la variable y usarla en el comando con la sintaxis $ : =.

$ unset x
$ if [-z "$ x"]; Entonces Echo Null; FI
NULO
$ echo $ x: = 2
2
$ if [-z "$ x"]; Entonces Echo Null; más eco $ x; FI
2

La expansión de la subcadena sustituirá desde un punto de desplazamiento, un cierto número de caracteres en la cadena

$ X = "Hola mundo"
$ echo $ x: 0: 7
Hola W

Cambie el desplazamiento al segundo carácter e imprima 7 caracteres de la subcadena

$ X = "Hola mundo"
$ echo $ x: 1: 7
ello wo

Subcadena desde el comienzo de la cadena pero corta los últimos 2 caracteres

$ X = "Hola mundo"
$ echo $ x: 0: -2
Hola Wor

Obtenga una longitud de cadena con esta versión de la expansión de parámetros

$ X = "Hola mundo"
$ echo $ #x
11

Buscar y reemplazar dentro de una variable. En este ejemplo, reemplace la primera O minúscula O con mayúscula O

$ X = "Hola mundo"
$ echo $ x/o/o
Hola Mundo

Buscar y reemplazar dentro de una variable pero con todas las coincidencias reemplazadas debido a la barra de búsqueda principal en el patrón de búsqueda.

$ X = "Hola mundo"
$ echo $ x // o/o
Hola Mundo

Patrones que comienzan con #, significan que la coincidencia debe comenzar al comienzo de la cadena para ser sustituido

$ X = "Hola mundo"
$ echo $ x/#h/j
Mundo de gelatina

Ejemplo donde busque el partido al comienzo de la cadena, pero falla porque el partido está más tarde en la cadena

$ X = "Hola mundo"
$ echo $ x/#w/j
Hola Mundo

Los patrones que comienzan con % solo coincidirán al final de la cadena como en este ejemplo.

$ X = "Hola mundo"
$ echo $ x/%d/d hoy
Hola mundo hoy

Ejemplo para el final de la coincidencia de cadena que falla porque la coincidencia está al comienzo de la cadena.

$ X = "Hola mundo"
$ echo $ x/%h/hoy
Hola Mundo

Use Shopt con Nocasematch para hacer un reemplazo insensible.

$ shopt -s nocasematch
$ X = "Hola mundo"
$ echo $ x/hello/bienvenido
Mundo de bienvenida

Apague Shopt con Nocasematch para hacer un reemplazo sensible a las carcajas.

$ shopt -u nocasematch
$ X = "Hola mundo"
$ echo $ x/hello/bienvenido
Hola Mundo

Buscar variables de entorno que coincidan con un patrón.

$ My_a = 1
$ My_b = 2
$ My_c = 3
$ echo $ !MI*
My_a my_b my_c

Obtenga una lista de variables coincidentes y luego realice cada variable e imprima su valor

$ My_a = 1
$ My_b = 2
$ My_c = 3
$ variables = $ !MI*
$ para i en $ variables; hacer eco $ i; echo "$ !i "; hecho
My_a
1
MI B
2
MI C
3

Haga una cadena todo el proceso superior

$ X = "Hola mundo"
$ echo $ x ^^
HOLA MUNDO
Hacer una cuerda en minúsculas
$ X = "Hola mundo"
$ echo $ x ,,
Hola Mundo
Haga el primer carácter de una cadena en mayúscula
$ X = "George Washington"
$ echo $ x^
George Washington
Haga el primer carácter de una minúscula de cuerda
$ X = bob
$ echo $ x,
Beto

Parámetros posicionales

Los parámetros posicionales normalmente se consideran parámetros de línea de comandos, cómo usarlos se muestran con ejemplos a continuación.

El parámetro $ 0 es el nombre del script que se está ejecutando y luego $ 1, $ 2, $ 3, etc. son parámetros de línea de comando pasados ​​a un script.

$ Cat Script.mierda
Echo $ 0
Echo $ 1
Echo $ 2
Echo $ 3
$ Bash ./guion.zanahoria de plátano de manzana
./guion.mierda
manzana
banana
zanahoria

El parámetro $* es una sola variable con todos los argumentos de la línea de comando concatenados.

$ Cat Script.mierda
Echo $ 1
Echo $ 2
Echo $*
$ Bash ./guion.SH Apple Banana
manzana
banana
manzana platano

El parámetro $# es un número con la cantidad de parámetros posicionales pasados ​​a un script en este caso a continuación. Se aproban 2 argumentos.

$ Cat Script.mierda
Echo $ 1
Echo $ 2
Echo $*
Echo $#
$ Bash ./guion.SH Apple Banana
manzana
banana
manzana platano
2

Expansión de Tilde

La expansión de Tilde se ve comúnmente con nombres de usuario y directorios de inicio, los ejemplos se muestran a continuación.

Expansión de Tilde para obtener el directorio de inicio del usuario actual, utilizando solo Tilde sin el nombre de usuario.

$ echo $ usuario
raíz
$ CD ~/
$ PWD
/raíz

Consulte el directorio de inicio de un usuario específico, no al usuario actual con Tilde y el nombre de usuario

$ CD ~ Linuxhint
$ PWD
/Inicio/Linuxhint

Sustitución aritmética

La sustitución aritmética permite a Bash realizar operaciones matemáticas en el shell o en un script. A continuación se muestran ejemplos de usos comunes.

Sustitución aritmética simple con $ y paréntesis dobles

$ Echo $ ((2 + 3))
5

Public Increment Operator actualizará el valor por uno después del comando actual, tenga en cuenta que hay una disminución de publicación equivalente que no se muestra aquí.

$ X = 2
$ Echo $ ((x ++))
2
$ echo $ x
3

El operador previo a la incremento actualizará el valor por uno justo antes del comando actual, tenga en cuenta que hay un operador de pre -disminución equivalente que no se muestra aquí.

$ X = 2
$ Echo $ ((++ x))
3
$ echo $ x
3

El operador de exponentes puede elevar un número a una potencia exponencialmente

$ Echo $ ((5 ** 2))
25

Cambio de bit a la izquierda; En este caso, cambie los bits del número decimal 8 a la izquierda que esencialmente lo multiplica por 2

$ Echo $ ((8<<1))
dieciséis

Cambio bit a bit derecho; En este caso, cambie los bits del decimal número 8 a la derecha que esencialmente divide el número por 2

$ Echo $ ((8 >> 1))
4

Bitwise y el operador compararán los números bit por bit y el resultado serán los bits que están establecidos.

$ Echo $ ((4 y 5))
4

Bitwise u operador comparará los números bit a poco y los resultados serán los bits donde cualquiera de las entradas tiene el bits establecido.

$ Echo $ ((4 | 9))
13

El operador de igualdad aritmética evaluará la verdad y el regreso 1 o 0

$ Echo $ ((4 == 4))
1

El operador de desigualdad aritmética evaluará la falta de igualdad y devolverá 1 o 0

$ Echo $ ((4 != 4))
0

El operador condicional probará el primer argumento si es verdadero, reemplazar con el segundo argumento y si falso reemplazar con el tercero. En este caso 5 es igual a 4+1, por lo que el primer condicional es verdadero y 9 se devuelve. 5 no es igual a 4+2, por lo que en el segundo eco 7 se devuelve.

$ Echo $ ((5 == 4+1 ? 9: 7))
9
$ Echo $ ((5 == 4+2 ? 9: 7))
7

Puede usar números hexadecimales en expansiones aritméticas, en este caso 0xa es equivalente a 10 y 10+7 = 17.

$ Echo $ ((0xa + 7))
17

División de palabras

Utilizando la variable de entorno IFS para registrar un delimitador, y utilizando los comandos Read y ReadArray podemos analizar las cadenas en una variedad de tokens y luego contar los tokens y operar con ellas. Los ejemplos se muestran a continuación.
Use el parámetro IFS como delimitador, lea los tokens en una matriz dividida por IFS que se establece en un carácter espacial y luego imprima los tokens uno por uno

$ text = "Hola mundo"
$ Ifs = "
$ Read -A Tokens <<< "$text"
$ echo "Hay $ #tokens [*] palabras en el texto."

Hay 2 palabras en el texto.

$ para i en "$ tokens [@]"; hacer eco $ i; hecho
Hola
Mundo

Usuario ReadArray sin ifs y especificar delimitador en el comando ReadArray. Tenga en cuenta que este es solo un ejemplo en el que dividimos una ruta de directorio basada en el delimitador de Slash. En este caso, el código ha incluido la cadena vacía antes de la primera barra de corte que necesitaría ajustarse en un uso real, pero solo mostramos cómo llamar a ReadArray para dividir una cadena en tokens en una matriz con un delimitador.

$ path = "/home/linuxhint/usr/local/bin"
$ Readarray -d / -t tokens <<< "$path"
echo "Hay $ #tokens [*] palabras en el texto."

Hay 6 palabras en el texto.

$ para i en "$ tokens [@]"; hacer eco $ i; hecho
hogar
Linuxhint
USR
local
papelera

Expansión del nombre de archivo

Cuando desee consultar una lista de archivos o directorios en el sistema de archivos, un comando bash o script bash puede usar la expansión del nombre de archivo para generar una lista de archivos y directorios a partir de comandos simples. Los ejemplos se muestran a continuación.

El * personaje se expande a un comodín y recoge todos los archivos coincidentes con el resto de la cadena de comodines. Aquí recogemos todos los archivos que terminan en .txt y pasarlos al comando du para verificar el tamaño del disco.

$ touch a.txt b.txt c.TXT
$ echo "Hello World"> contenido.TXT
$ du *.TXT
0 A.TXT
0 B.TXT
0 C.TXT
4 contenido.TXT

El ? El personaje solo coincidirá con un solo personaje, no un número infinito de caracteres, y por lo tanto, en este ejemplo, solo recogerá nombres de archivo con un solo carácter seguido de .TXT.

$ touch a.txt b.txt c.TXT
$ echo "Hello World"> contenido.TXT
$ du ?.TXT
0 A.TXT
0 B.TXT
0 C.TXT

Los personajes de los paréntesis se expanden para que coincidan con cualquiera de los personajes. En este ejemplo a.txt y c.TXT son recogidos por la expansión

$ touch a.txt b.txt c.TXT
$ echo "Hello World"> contenido.TXT
$ du [ac].TXT
0 A.TXT
0 C.TXT

Los personajes de los paréntesis pueden ser una variedad de caracteres y vemos aquí todos los archivos de una gama A a C seguidas de .El sufijo txt se recoge

$ touch a.txt b.txt c.TXT
$ echo "Hello World"> contenido.TXT
$ du [A-C].TXT
0 A.TXT
0 B.TXT
0 C.TXT

Conclusión

Hemos cubierto muchos tipos de expansiones de conchas en este artículo, y espero que los ejemplos simples puedan servir como un libro de cocina para lo que es posible en Bash para que sea más productivo con las expansiones de la concha. Como referencias adicionales, recomiendo leer el manual de Bash completo, y también los muchos buenos artículos en el sitio web de Nixcraft sobre Scripting Bash, incluidas las expansiones de Shell. Tenemos otros artículos que pueden ser de interés para usted en Linuxhint que incluyen: 30 ejemplos de guiones de bash, cadenas mayúsculas en minúsculas, coincidencia de patrones de bash y ejemplos de cadena dividida de bash. También tenemos un popular curso gratuito de 3 horas en programación bash que puede encontrar en YouTube.