idiome `set -e` et` grep` pour empêcher la sortie prématurée du script shell lorsque le modèle n'est pas trouvé

15

Aide requise - dans le contexte des scripts shell sur un bash GNU / LINUX:

J'utilise toujours set -e. Souvent, je voudrais grepet je ne veux pas toujours que le script termine l'exécution s'il grepa un statut de sortie 1indiquant un modèle introuvable.

J'ai essayé de résoudre ce problème comme suit:

(Essayez I)
Si set +o pipefailet invoquez grep avec quelque chose comme grep 'p' | wc -lça, j'obtiens le comportement souhaité jusqu'à ce qu'un futur responsable le permette pipefail. De plus, j'aime l'activation, pipefaildonc cela ne fonctionne pas pour moi.

(Essayez II)
Utilisez un sedou awket seulement imprimer le motif correspondant aux lignes, puis wcles lignes correspondantes pour tester le motif correspondant. Je n'aime pas cette option car l'utilisation sedde grepsemble être une solution de contournement pour mon vrai problème.

(Essayez III)
Celui-ci est mon moins préféré - quelque chose comme:set +e; grep 'p'; set-e

Tout aperçu / idiome serait très apprécié - merci.

Yeow_Meng
la source

Réponses:

19

Vous pouvez mettre le grep dans une ifcondition, ou si vous ne vous souciez pas du statut de sortie, ajoutez || true.

Exemple: greptue le shell

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

solution 1: jeter le statut de sortie non nul

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

solution 2: tester explicitement l'état de sortie

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

De la page de manuel de bash discutant set -e:

La coque ne sort pas si la commande qui ne fait partie de la liste de commande suivante immédiatement tout ou jusqu'à ce mot - clé, une partie du test suivant les cas ou Elif mots réservés, partie d'une commande exécutée dans un && ou ││ liste à l' exception du après le && ou ││ final , n'importe quelle commande dans un pipeline sauf le dernier, ou si la valeur de retour de la commande est inversée avec ! .

glenn jackman
la source
Étant donné que bash pendant une longue période n'a pas implémenté -e correctement, il se peut que la documentation ne soit pas encore correcte. Comme le texte semble être identique à la page de manuel bash-3.x, veuillez noter: toutes les versions de bash avant bash4.0 ont implémenté -e incorrectement.
schily
Notez également que la norme POSIX étant également erronée, nous avons modifié le texte POSIX pour la gestion des erreurs avec -e en 2009
schily
1
@schily Veuillez indiquer où l'on peut trouver quel est le comportement «correct» de -e, ce que bash <4 a fait différemment et ce qui a été changé dans POSIX.
zwol
Les bogues de bash-3 le rendent fondamentalement inutilisable makecar il ne se terminait pas toujours par des erreurs. Pour les discussions POSIX connexes, vous aimerez peut-être vérifier austingroupbugs.net
schily
@schily Pourriez-vous s'il vous plaît être plus précis?
zwol