`set -e` e` grep` idioma per impedire l'uscita prematura dallo script della shell quando non viene trovato il pattern


15

Aiuto richiesto - nel contesto dello scripting di shell su una bash GNU / LINUX:

Lo uso sempre set -e. Spesso, vorrei grepe non sempre desidero che lo script termini l'esecuzione se grepha uno stato di uscita che 1indica un modello non trovato.

Qualcosa che ho provato a risolvere questo problema è il seguente:

(Prova I)
Se set +o pipefaile invoco grep con qualcosa del genere, grep 'p' | wc -lottengo il comportamento desiderato fino a quando un futuro manutentore lo abilita pipefail. Inoltre, mi piace abilitare pipefailquindi questo non funziona per me.

(Prova II)
Utilizzare uno sedo awksolo le linee di stampa corrispondenti al motivo, quindi le wclinee abbinate per verificare il motivo abbinato. Non mi piace questa opzione perché usare sedto grepsembra una soluzione alternativa al mio vero problema.

(Prova III)
Questo è il mio meno preferito - qualcosa del tipo:set +e; grep 'p'; set-e

Qualsiasi intuizione / idioma sarebbe molto apprezzato - grazie.

Risposte:


19

Puoi mettere grep in una ifcondizione, o se non ti interessa lo stato di uscita, aggiungi || true.

Esempio: grepuccide la shell

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

soluzione 1: elimina lo stato di uscita diverso da zero

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

soluzione 2: testare esplicitamente lo stato di uscita

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

Dalla pagina man di bash che parla di set -e:

La shell non si chiude se il comando che fallisce fa parte dell'elenco dei comandi immediatamente dopo un po ' o fino alla parola chiave, parte del test che segue le parole riservate if o elif , parte di qualsiasi comando eseguito in un elenco && o ││ ad eccezione del comando che segue l'ultimo && o ││ , qualsiasi comando in una pipeline tranne l'ultimo, o se il valore di ritorno del comando viene invertito con ! .


Dato che bash per lungo tempo non è stato implementato correttamente, è possibile che la documentazione non sia ancora corretta. Poiché il testo sembra essere identico alla pagina man bash-3.x, si noti che tutte le versioni bash precedenti a bash4.0 hanno implementato -e in modo errato.
schily,

Inoltre, poiché lo standard POSIX era errato, abbiamo modificato il testo POSIX per la gestione degli errori con -e nel 2009
schily,

1
@schily Per favore, dai indicazioni su dove si può scoprire quale sia il comportamento 'corretto' di -e, cosa bash <4 ha fatto diversamente e cosa è cambiato in POSIX.
zwol,

I bug in bash-3 lo rendono sostanzialmente inutilizzabile perché makenon sempre usciva in caso di errori. Per le discussioni relative POSIX, come si può verificare austingroupbugs.net
Schily

@schily Potresti essere più specifico per favore?
zwol,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.