¿Cómo puedo importar la salida de un comando como un comando en Bash?

8

Sistema

Linux hosek 4.15.0-48-generic #51-Ubuntu SMP Wed Apr 3 08:28:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Problema

Necesito obtener resultados como comandos, en un script bash, para almacenar variables.

Ejemplo

sed -n '/# Main configuration./,/# Websites./p' webcheck-$category.cfg | sed '1,1d' | sed '$ d'

Este comando devuelve estas líneas:

email_sender='[email protected]'
email_recipients='[email protected]'

¿Cómo puedo leer / ejecutar estos resultados / líneas como comandos en el script? ¿Almacenar esta salida en el archivo y luego leerlo solo por sourcecomando?

Intenté | sourceal final del comando, pero solo se lee de los archivos.

Lo intenté echoal principio, pero eso no tuvo ningún efecto.

Gracias.

génerobee
fuente

Respuestas:

15

Como pLumo te mostró , de hecho puedes hacerlosource . Sin embargo, recomendaría contra esto. Si tienes algo como esto:

source <(sed -n '/# Main configuration./,/# Websites./p' webcheck-$category.cfg | sed '1,1d' | sed '$ d')

echo "$email_sender"

Luego, un año después, cuando regrese y vea este script, no tendrá idea de dónde email_senderproviene esta variable. Le sugiero que cambie el comando y use uno que devuelva solo el valor de la variable y no su nombre. De esa manera, puede realizar un seguimiento fácil de dónde proviene cada variable:

email_sender=$(grep -oP 'email_sender=\K.*' webcheck-$category.cfg)
email_recipients=$(grep -oP 'email_recipients=\K.*' webcheck-$category.cfg)
terdon
fuente
Estoy de acuerdo en que esto es mejor ;-) Al menos para los scripts que pretendes usar más adelante.
pLumo
Gracias a los dos! Agradable y simple ;)
genderbee
Para dos esto está bien, para más uso para bucles con una dirección indirecta: for var in email_sender email_recipient email_subject email_attachement etc ; do printf -v "${var}" '%s' "$(grep -oP $var'=\K.*' webcheck-$category.cfg)"; doneSin embargo, esto falla los criterios "simples".
Ley29
3

Puede usar la sustitución de procesos :

source <(sed -n '/# Main configuration./,/# Websites./p' webcheck-$category.cfg | sed '1,1d' | sed '$ d')
pLumo
fuente
0
#!/bin/bash

declare -A data
while IFS='=' read -r key value; do
    data[$key]=${value//\'/}
done < <(grep -E '^([^#].+=.*)' webcheck-$category.cfg)

o

done < <(sed -n '/# Main configuration./,/# Websites./{//!p}' webcheck-$category.cfg)
# associative array.
echo ${data[email_sender]}
echo ${data[email_recipients]}

Salida:

[email protected] [email protected]

bac0n
fuente
-1

bash read builtin maneja cosas como esta muy bien.

read -d '' -r email_sender email_recipients < <(
  grep -oP 'email_sender=\K.*' webcheck-$category.cfg; 
  grep -oP 'email_recipients=\K.*' webcheck-$category.cfg
)

readlee líneas de stdin en variables. -d ''desactiva la división de espacios en blanco, excepto las nuevas líneas. -rdesactiva los \escapes.

cmdA < <(cmdB)funciona de manera similar a cmdB | cmdA, excepto en el anterior cmdA, se ejecuta en ~ este ~ shell, en lugar de un subshell, que es necesario para que la lectura funcione como se espera.

Evan Benn
fuente
1
¿Puedes dar alguna explicación sobre las diferentes partes de la línea?
Simon Sudler
Esto es cierto, pero ¿cómo es relevante para la pregunta formulada dónde se debe leer el objetivo de un archivo var=value?
terdon