Comment rediriger la sortie vers une variable dans shell?
j'ai un script comme ça
genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5
je veux obtenir flux généré par genhash dans une variable. Comment puis-je le rediriger dans une variable $hash
pour comparer à l'intérieur d'un conditionnel?
if [ $hash -ne 0 ]
then echo KO
exit 0
else echo -n OK
exit 0
fi
8 réponses
TL; DR
pour stocker "abc"
en $foo
:
echo "abc" | read foo
bien sûr, toutes ces autres réponses montrent des façons de ne pas faire ce que L'OP a demandé, mais cela a vraiment foutu en l'air le reste d'entre nous qui avons cherché la question de L'OP.
la réponse à la question Est d'utiliser le read
commandement.
Voici comment vous le faites
# I would usually do this on one line, but for readability...
series | of | commands \
| \
(
read string;
mystic_command --opt "$string" /path/to/file
) \
| \
handle_mystified_file
voici ce qu'il fait et pourquoi il est important:
-
disons que le
series | of | commands
est une série très compliquée de commandes pipées. -
mystic_command
peut en accepter le contenu d'un fichier stdin en lieu et place d'un chemin d'accès au fichier, mais , pas la--opt
arg par conséquent, il doit venir comme une variable. La commande produit le contenu modifié et serait généralement redirigé dans un fichier ou pipé à une autre commande. (P. ex..sed
,awk
,perl
, etc.) -
read
prend stdin et le place dans la variable$string
-
mettre le
read
et lemystic_command
dans un" sous-shell " via la parenthèse n'est pas nécessaire mais le rend le flux comme un tuyau continu comme si les 2 commandes où dans un dossier de script séparé.
il y a toujours une alternative, et dans ce cas l'alternative est laide et illisible par rapport à mon exemple ci-dessus.
# my example above as a oneliner
series | of | commands | (read string; mystic_command --opt "$string" /path/to/file) | handle_mystified_file
# ugly and unreadable alternative
mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file
à Ma façon chronologique et logique. L'alternative commence avec la 4ème commande et pousse les commandes 1, 2 et 3 dans la substitution de commande.
read hash < <(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)
Cette technique utilise Bash " processus de substitution "à ne pas confondre avec" la substitution de commande ".
Voici quelques bonnes références:
je suppose voie compatible:
hash=`genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5`
mais je préfère
hash="$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)"
si un pipeline est trop compliqué à envelopper dans $(...)
, envisager d'écrire une fonction. Toute variable locale disponible au moment de la définition sera accessible.
function getHash {
genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5
}
hash=$(getHash)
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Functions
Vous pouvez le faire:
hash=$(genhash --use-ssl -s $IP -p 443 --url $URL)
ou
hash=`genhash --use-ssl -s $IP -p 443 --url $URL`
si vous voulez que le résultat de la totalité du tuyau soit affecté à la variable, vous pouvez utiliser la totalité du pipeline dans les attributions ci-dessus.
créez une fonction l'appelant comme la commande que vous voulez invoquer. Dans ce cas, je dois utiliser la commande ruok .
ensuite, appelez la fonction et assignez son résultat dans une variable. Dans ce cas, j'attribue le résultat à la variable santé .
function ruok {
echo ruok | nc *ip* 2181
}
health=echo ruok *ip*
j'ai parfois eu une erreur en utilisant le constructeur $(`code`)
.
finalement j'ai eu une certaine approche de cela ici: https://stackoverflow.com/a/7902174/2480481
essentiellement, en utilisant Tee pour relire l'ouput et le mettre dans une variable. Il y a la façon de voir la sortie normale, puis de la lire à partir de la sortie.
n'est pas? Je suppose que votre tâche actuelle genhash produira juste cela, un simple hachage de chaîne de caractères ainsi pourrait fonctionner pour vous.
Im so neewbie et toujours à la recherche d'une sortie totale et enregistrer en 1 commande. Égard.