web-dev-qa-db-fra.com

Comment rediriger la sortie vers une variable en shell?

J'ai un script comme ça

genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5

Je veux obtenir le flux généré par genhash dans une variable. Comment puis-je le rediriger vers une variable $hash afin de le comparer dans une condition?

if [ $hash -ne 0 ]
  then echo KO
  exit 0
else echo -n OK
  exit 0
fi
181
markcial

Utilisez la construction $( ... ):

hash=$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)
306
anon

TL; DR

Pour stocker "abc" dans $foo:

echo "abc" | read foo

Mais, comme les tuyaux créent des fourchettes, vous devez utiliser $foo avant la fin du tuyau, alors ...

echo "abc" | ( read foo; date +"I received $foo on %D"; )

Bien sûr, toutes ces autres réponses montrent des moyens de ne pas faire ce que le PO a demandé, mais cela fâche vraiment le reste d'entre nous qui avons cherché la question du PO.

La réponse à la question est d'utiliser la commande read.

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 c'est important:

  1. Supposons que le series | of | commands est une série très compliquée de commandes canalisées.

  2. mystic_command peut accepter le contenu d'un fichier en tant que stdin au lieu d'un chemin de fichier, mais pas le --opt arg il doit donc entrer en tant que variable. La commande génère le contenu modifié et est généralement redirigée vers un fichier ou transmise à une autre commande. (Par exemple, sed, awk, Perl, etc.)

  3. read prend stdin et le place dans la variable $string

  4. Placer read et le mystic_command dans un "sous-shell" entre parenthèses n'est pas nécessaire, mais le fait défiler comme un tuyau continu, comme si les 2 commandes étaient dans un fichier script séparé.

Il y a toujours une alternative, et dans ce cas l'alternative est moche 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

Mon chemin est entièrement chronologique et logique. L'alternative commence par la 4ème commande et enfonce les commandes 1, 2 et 3 dans la substitution de commande.

J'ai un exemple du monde réel dans ce script mais je ne l'ai pas utilisé comme exemple ci-dessus car il contient une autre magie folle/déroutante/distrayante.

187
Bruno Bronosky
read hash < <(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)

Cette technique utilise le " substitution de processus " de Bash à ne pas confondre avec " substitution de commande ".

Voici quelques bonnes références:

53
Steven Penny

Je suppose que de manière 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)"
18
ony

Si un pipeline est trop compliqué à intégrer dans $(...), envisagez d'écrire une fonction. Toutes les variables locales disponibles au moment de la définition seront accessibles.

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

5
Huuu

Tu peux 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 tuyau entier soit affecté à la variable, vous pouvez utiliser tout le pipeline dans les affectations ci-dessus.

3
codaddict

Créez une fonction en l'appelant en tant que commande à appeler. Dans ce cas, je dois utiliser la commande ruok.

Appelez ensuite la fonction et affectez son résultat à une variable. Dans ce cas, j'assigne le résultat à la variable santé.

function ruok {
  echo ruok | nc *ip* 2181
}

health=echo ruok *ip*
1
Arena Hernandez

J'ai parfois des erreurs lorsque j'utilise le constructeur $(`code`).

Enfin, j'ai eu une approche à ce sujet ici: https://stackoverflow.com/a/7902174/2480481

En gros, utiliser Tee pour relire le résultat et le mettre dans une variable. Voici comment vous voyez la sortie normale puis lisez-la à partir de la sortie.

n'est pas? J'imagine que votre tâche actuelle, genhash, ne produira que cela, un hachage à chaîne unique pourrait donc fonctionner pour vous.

Je suis tellement novice et cherche toujours la sortie complète et la sauvegarde en 1 commande. Cordialement.

1
erm3nda