Comment puis-je importer la sortie d'une commande en tant que commande dans Bash?

8

Système

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

Problème

J'ai besoin d'obtenir une sortie sous forme de commandes, dans un script bash, pour stocker des variables.

Exemple

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

Cette commande renvoie ces lignes:

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

Comment puis-je lire / exécuter ces sorties / lignes en tant que commandes dans le script? Est-ce que le stockage de cette sortie dans le fichier, puis la lecture par sourcecommande uniquement?

J'ai essayé | sourceà la fin de la commande, mais elle ne lit que les fichiers.

J'ai essayé echoau début, mais cela n'a eu aucun effet.

Merci.

abeille
la source

Réponses:

15

Comme pLumo vous l'a montré , vous pouvez en effet sourceles utiliser . Cependant, je recommanderais contre cela. Si vous avez quelque chose comme ça:

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

echo "$email_sender"

Puis, un an plus tard, lorsque vous reviendrez et regarderez ce script, vous n'aurez aucune idée d'où vient cette email_sendervariable. Je vous suggère plutôt de modifier la commande et d'en utiliser une qui renvoie uniquement la valeur de la variable et non son nom. De cette façon, vous pouvez facilement suivre d'où vient chaque variable:

email_sender=$(grep -oP 'email_sender=\K.*' webcheck-$category.cfg)
email_recipients=$(grep -oP 'email_recipients=\K.*' webcheck-$category.cfg)
terdon
la source
Je suis d'accord que c'est mieux ;-) Au moins pour les scripts que vous avez l'intention d'utiliser plus tard.
pLumo
Merci aux deux! Agréable et simple. ;)
genderbee
Pour deux c'est OK, pour plus j'utilise pour des boucles avec une indirection: for var in email_sender email_recipient email_subject email_attachement etc ; do printf -v "${var}" '%s' "$(grep -oP $var'=\K.*' webcheck-$category.cfg)"; doneCependant cela échoue aux critères "simples".
Loi29
3

Vous pouvez utiliser la substitution de processus :

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

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

ou

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

Production:

[email protected] [email protected]

bac0n
la source
-1

bash read builtin gère bien des choses comme ça.

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

readlit les lignes de stdin en variables. -d ''désactive le fractionnement des espaces, sauf pour les retours à la ligne. -rdésactive les \évasions.

cmdA < <(cmdB)fonctionne de manière similaire à cmdB | cmdA, sauf dans l'ancien cmdA est exécuté dans ~ ce ~ shell, au lieu d'un sous-shell, qui est requis pour que la lecture fonctionne comme prévu.

Evan Benn
la source
1
Pouvez-vous donner quelques explications sur les différentes parties de la ligne?
Simon Sudler
C'est vrai, mais en quoi est-il pertinent pour la question posée où l'objectif est de lire un fichier avec var=value?
terdon