177 votes

Vérifier si la sortie d'une commande contient une certaine chaîne dans un shell script.

J'écris un shell script, et j'essaie de vérifier si la sortie d'une commande contient une certaine chaîne. Je pense que je dois probablement utiliser grep, mais je ne suis pas sûr de savoir comment. Quelqu'un le sait-il ?

209voto

mat Points 5365

Essais $? es un anti-modèle.

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi

165voto

perreal Points 47912

Tester la valeur de retour de grep :

./somecommand | grep 'string' &> /dev/null
if [ $? == 0 ]; then
   echo "matched"
fi

ce qui se fait de manière idiomatique comme suit :

if ./somecommand | grep -q 'string'; then
   echo "matched"
fi

et aussi :

./somecommand | grep -q 'string' && echo 'matched'

14voto

Noam Manos Points 145

Une autre option consiste à vérifier la correspondance d'une expression régulière sur la sortie de la commande.

Par exemple :

[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"

10voto

Ehsan Barkhordar Points 658

Un shell conditionnel propre if/else script :

si (ls | grep '$1') alors echo "exists" (existe) sinon echo "n'existe pas". fi

4voto

F1Linux Points 129

RÉPONSE COURTE

Toutes les réponses ci-dessus (très excellentes) supposent toutes que grep peut "voir" la sortie de la commande, ce qui n'est pas toujours vrai :

SUCCÈS peut être envoyé à STDOUT tandis que FAILURE a STDERR .

Donc, selon la direction que vous testez, votre grep peut échouer. C'est à dire que si vous testez le cas de FAILURE vous devez rediriger la sortie de la commande vers STDOUT en utilisant 2>&1 dans un cas comme celui-ci.

REPONSE LONGUE avec PROOFS

J'avais ce que je pensais être un test très simple dans un script bash utilisant grep et ça a continué à échouer. Il s'en est suivi beaucoup de remue-méninges. L'utilisation de set -x dans mon script a révélé que la variable était vide ! J'ai donc créé le test suivant pour comprendre comment les choses se cassaient.

NOTE : iscsiadm est un outil Linux du groupe " open-iscsi Paquet " utilisé pour connecter/déconnecter un hôte au stockage SAN. La commande iscsiadm -m session est utilisé pour montrer si des connexions LUN sont établies) :

#!/bin/bash

set -x

TEST1=$(iscsiadm -m session)
TEST2=$(iscsiadm -m session 2>&1)
echo
echo 'Print TEST1'
echo $TEST1
echo
echo 'Print TEST2'
echo $TEST2
echo

Si un LUN WAS connecté, les DEUX variables ont été remplies de valeurs avec succès :

Print TEST1
tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash)

Print TEST2
tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash)

Cependant, si un LUN N'ÉTAIT connecté, iscsiadm a envoyé la sortie à STDERR, et seulement le " TEST2 La variable " a été remplie là où nous avions redirigé vers STDOUT en utilisant la variable 2>&1 ; " TEST1 La variable " qui n'avait pas de redirection vers STDOUT était vide :

iscsiadm: No active sessions.

Print TEST1

Print TEST2
iscsiadm: No active sessions.

CONCLUSION

Si vous avez un funky, à moitié cassé fonctionne dans un sens mais pas dans l'autre - dans une telle situation, essayez le test ci-dessus en remplaçant iscsiadm avec votre propre commande et vous devriez obtenir la visibilité appropriée pour réécrire votre test afin qu'il fonctionne correctement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X