Cuando trabaje con scripts de Bash, puede terminar en una situación en la que tenga que procesar una serie de entradas con el mismo comando. Afortunadamente, hay una forma en Bash de lograr esto de una manera más óptima usando HereDoc .
HereDoc, acrónimo de Here Document , es una redireccionamiento de entrada método para pasar múltiples entradas a un programa o comando. El concepto de heredoc no está relacionado exclusivamente con Bash. Muchos lenguajes de programación populares como Perl, Ruby, PHP son compatibles con heredoc.
En este artículo, veremos la sintaxis y el uso de heredoc con algunos casos de uso del mundo real. Todos los ejemplos en este artículo están creados para ser simples, de modo que incluso un novato pueda entender este concepto fácilmente. Entremos y empecemos a jugar con heredoc en Bash.
Sintaxis de HereDoc
El siguiente diagrama ilustra la sintaxis de heredoc.
Aquí,
- Comando - Cualquier comando (cat, wc, mail, etc.) que acepte la redirección.
- Operador de redirección (
<<
) - El operador predeterminado para HereDoc es<<
. Redirige el bloque de código al comando para su procesamiento. - Token delimitador - El token delimitador indica el inicio y el final del documento (bloque de código). El token delimitador puede ser cualquier cosa, pero debe ser idéntico. Normalmente verá
EOF
se utiliza como tokens delimitadores que significan "Fin del flujo de archivos".
Impresión de cadenas de varias líneas usando HereDoc en Bash
Comencemos con un ejemplo simple de redirigir una cadena de varias líneas e imprimirla en la terminal.
El cat
El comando acepta un flujo de entradas y con heredoc, y puede redirigir el bloque de código para imprimirlo en la terminal.
$ cat << EOF Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
Salida:
Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <==
Eche un vistazo al fragmento de código anterior. Tengo tres líneas que se redireccionan al cat
dominio. estoy usando EOF
como delimitador. Sin embargo, puede usar cualquier cosa que desee, pero mantenga idénticos los delimitadores inicial y final.
Intentemos con un ejemplo más simple. Estoy redirigiendo las mismas tres líneas a recuento de palabras programa. Estoy usando un delimitador diferente (BLK
) aquí.
$ wc -l << BLK Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== BLK
Salida de muestra:
3
Redireccionamiento y canalización en HereDoc
Puede combinar el operador de redirección de salida con heredoc y redirigir la salida a un archivo en lugar de imprimirlo en la terminal.
Estoy usando el mismo ejemplo que usé en la sección anterior y redirigiendo la salida a un archivo llamado log_op.txt
.
$ cat << EOF > /tmp/log_op.txt Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
La salida de heredoc se puede enviar a la tubería operador para su posterior procesamiento.
$ cat << EOF | grep -i sla Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
Supresión de pestañas en HereDoc
Cuando haya espacios en blanco (pestañas) en su bloque de código y si desea suprimirlo, use "-"
después del operador de redirección. Un punto importante a tener en cuenta es que solo se suprimirán las tabulaciones, no los espacios.
Eche un vistazo al siguiente ejemplo. He añadido una declaración condicional al mismo ejemplo que hemos visto en secciones anteriores. Las dos primeras líneas en heredoc están tabuladas (4) y la tercera línea está espaciada (2).
if [[ $x = "err" ]] then cat <<- err_msg 1. Something is wrong with the input file received for today. 2. Contact the downstream team to get it corrected. 3. ==> SLA MISSED <== err_msg fi
Cuando se envíe el fragmento de código, mi resultado será el siguiente.
1. Something is wrong with the input file received for today. 2. Contact the downstream team to get it corrected. 3. ==> SLA MISSED <==
Como puede ver, las pestañas de la línea 1 y 2 están suprimidas, pero en la línea 3, ya que se usan espacios, no se suprime.
Expansión de variables y comandos en HereDoc
No es que solo pueda pasar cadenas dentro del bloque de código heredoc. Puede pasar variables ambientales y definidas por el usuario y ejecutar comandos dentro del bloque de código.
Eche un vistazo al siguiente ejemplo. Dentro del bloque de código, tengo una variable definida por el usuario "${AUTHOR}"
, una variable ambiental "${SHELL}"
, un comando externo "whoami"
.
Cuando se envía este fragmento, las variables y los comandos se expandirán y luego se redirigirán al cat
comando.
AUTHOR="OSTechNix" cat << EOF Author: ${AUTHOR} # USER DEFINED VARIABLE Article: Bash Heredoc I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Salida de muestra:
Author: OsTechnix Article: Bash Heredoc I am using the /bin/bash shell karthick
Puede encerrar el delimitador inicial con comillas simples para suprimir la expansión dentro del bloque de código. De esta forma, todo lo que esté dentro del bloque de código se tratará como una cadena literal.
cat << 'EOF' Author: ${AUTHOR} # USER DEFINED VARIABLE Article: Bash Heredoc I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Salida de muestra:
Author: ${AUTHOR} Article: Bash Heredoc I am using the ${SHELL} shell $(whoami)
Comentarios de varias líneas con HereDoc
Como ya sabrá, Bash no admite comentarios de varias líneas. Con heredoc, puede crear comentarios de varias líneas redirigiendo el bloque de código a no-op
comando (:
).
El no-op
es bash incorporado que toma la entrada y devuelve el código de salida cero. Puede considerar esto como un sinónimo del "true" incorporado de bash que también sale del código de salida cero.
: << 'COMMENTS' Author : OStechnix Article : Bash Heredoc BashV : 5.1.4 OS : PoP!_OS COMMENTS
Aviso: Casi todos los editores de texto tienen la función de seleccionar varias líneas y le permiten comentar o descomentar presionando una tecla. Es mejor seguir con este enfoque.
Escapar de caracteres especiales en HereDoc
Los bloques de código pueden contener caracteres especiales. Si desea escapar de los caracteres especiales, hay algunas formas de hacerlo.
Puede encerrar el delimitador con único o comillas dobles o barra invertida de prefijo con el delimitador. De esta forma, se escaparán todos los caracteres especiales.
# SINGLE QUOTES ESCAPE cat << 'EOF' I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
# DOUBLE QUOTES ESCAPE cat << "EOF" I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
# BACKSLASH ESCAPE cat << \EOF I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
En lugar de escapar todos los caracteres especiales, también puede escapar caracteres especiales particulares dentro del bloque agregando una barra invertida antes de cualquier caracter especial.
cat << EOF I am using the \${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Salida de muestra:
I am using the ${SHELL} shell karthick
Caso de uso de HereDoc
Hasta ahora hemos visto la construcción central de heredoc y su uso básico. Ahora veamos algunos casos de uso de la vida real. En mi experiencia, he usado heredoc cuando trabajo con ssh y clientes de bases de datos donde tengo que ejecutar un grupo de comandos.
Ejemplo 1:Ejecución como un usuario diferente dentro del script
En algunos casos, es posible que desee ejecutar ciertas partes de su código como un usuario diferente. En ese caso, puede usar heredoc para redirigir los comandos para que se ejecuten como un usuario diferente.
Eche un vistazo al siguiente ejemplo. Estoy redirigiendo el bloque de código a su
comando que cambiará al usuario a "ostechnix" y creará un archivo llamado test si no existe.
su - ostechnix << EOF if [[ ! -f /home/ostechnix/test ]];then touch /home/ostechnix/test echo "File Created" else echo "File exists" fi EOF
Ejemplo 2:uso de HereDoc con DB Client
Cuando desee ejecutar una serie de comandos en una base de datos, heredoc será útil.
Eche un vistazo al siguiente ejemplo. Estoy interactuando con el cliente MongoDB mongosh y dentro de heredoc, se pasan comandos de bloque de código para crear una nueva base de datos, una colección y agregar un documento de muestra.
mongosh << EOF use ostechnix db.data.insertOne({ "Site" : "OsTechnix", "DB" : "Mongo" }) db.data.find().pretty() EOF
Puede o no conocer MongoDB, pero está bien. Esto es solo para mostrar cómo usar heredoc para interactuar con clientes de db. Puede usar cualquier cliente de base de datos como MySQL, psql, sqlite según la base de datos con la que esté trabajando.
Ejemplo 3:ejecución de comandos remotos con HereDoc y SSH
Cuando desee ejecutar comandos en el servidor remoto, puede usar heredoc en combinación con ssh
dominio. Normalmente usando ssh
comando, puede ejecutar comandos en el servidor remoto de la siguiente manera.
$ ssh [email protected] "command"
Debe repetir el mismo comando una y otra vez si desea ejecutar más comandos en el host remoto. Con heredoc, puede agrupar todos los comandos y ejecutarlos.
$ ssh -T [email protected] << EOF Command 1... Command 2.. ..... Command N.. EOF
Cuando es necesario ejecutar el mismo código en varios nodos, puede agregar for loop
junto con heredoc. Estoy usando el mismo fragmento de código de creación de archivos que hemos visto en el primer ejemplo.
- La variable de matriz "servidor" contiene la lista de nombres de servidores.
- El bucle For itera sobre la variable de matriz.
- El comando de creación de archivos se pasa al comando SSH que iterará y creará archivos en cada servidor. Asegúrate de agregar
-T
marca al comando ssh que deshabilitará la asignación de pseudo-terminal.
declare -a server=( host1 host2 host3 ) for host in ${server[@]} do ssh -T [email protected]${host} << EOF echo "Running at host - ${host}" if [[ ! -f /home/ostechnix/test ]];then touch /home/ostechnix/test echo "File Created" else echo "File exists" fi EOF done
Conclusión
Heredoc es un concepto importante para comprender y usar en los scripts de Bash. Cuando escriba muchos scripts, llegará a saber más sobre heredoc y las formas de usarlo de manera óptima.
Si nunca antes ha usado heredoc, inicie la terminal y pruebe todos los fragmentos de código del artículo para comprenderlo mejor.
Lectura relacionada:
- Secuencias de comandos de Bash:variables explicadas con ejemplos
- Bash Scripting:funciones explicadas con ejemplos
- Comando Bash Echo explicado con ejemplos en Linux
- Secuencias de comandos de Bash:bucle For explicado con ejemplos
- Secuencias de comandos de Bash:ciclo while y till explicado con ejemplos