Perché è il comando modello “|| vero ”utile?


79

Attualmente sto esplorando i pacchetti Debian e ho letto alcuni esempi di codice. E su ogni riga, ad esempio, lo postinstscript è un modello.

some command || true
another command || true

Quindi se un comando fallisce, la riga ritorna vera ma non vedo come questo influisca sull'output del programma.


5
Cordiali saluti, ||:è un altro modo idiomatico di scrivere questo ( :essendo un'altra voce nella tabella incorporata che punta a true- ma garantisce di essere un builtin anche indietro a Bourne; che detto, per POSIX sh, trueè anche garantito che sia un builtin - quindi è più terseness che efficienza nei tempi anche remotamente moderni).
Charles Duffy,

Risposte:


151

La ragione di questo modello è che gli script del manutentore nei pacchetti Debian tendono ad iniziare set -e, il che provoca la chiusura della shell non appena un comando (in senso stretto, pipeline, elenco o comando composto) esce con uno stato diverso da zero. Questo assicura che gli errori non si accumulino: non appena qualcosa va storto, lo script si interrompe.

Nei casi in cui un comando nello script può fallire, l'aggiunta || truegarantisce che il comando composto risultante esca sempre con lo stato zero, quindi lo script non si interrompe. Ad esempio, la rimozione di una directory non dovrebbe essere un errore irreversibile (impedire la rimozione di un pacchetto); quindi useremmo

rmdir ... || true

poiché rmdirnon ha un'opzione per dirgli di ignorare gli errori.


4
Bene, senza set -eche sia necessario || true, ho pensato che fosse importante fornire il contesto. Se noti cose strane su POWER, ti incoraggio vivamente a presentare bug ( reportbug)!
Stephen Kitt,

16
@MichaelFelt, in realtà set -enon è solo una "convenzione Debian", ma un buon modello di programmazione che si dovrebbe sempre usare. Vedere. ad es. davidpashley.com/articles/writing-robust-shell-scripts
kay

2
per la domanda qui - perché usare || trueset -e è il contesto probabile e probabilmente il più comune. Mi inchino a questa risposta! Letteralmente, è utile ogni volta che lo stato di uscita è ritenuto irrilevante E (come si aggiunge il link dell'articolo) Non sto usando lo stato di uscita come parte del mio controllo di script. Vedo l'utilità (in set -e) ma non andrebbe così lontano come l'articolo e dice "Ogni script che scrivi dovrebbe includere set -e in alto". È uno stile di programmazione. "SEMPRE | Ogni" include il proprio set di trappole - aka - absolutes re: le soluzioni jolly si ALWAYSritorceranno contro alla fine aka - nessuna corsa gratuita.
Michael Felt,

1
@Kay Questa è una prospettiva attualmente popolare ma alla fine è impantanata con numerosi presupposti che limitano la portabilità della sceneggiatura. Ci sono incoerenze storiche con il set -ecomportamento. Potrebbe non interessarti, se i tuoi unici obiettivi sono bashe le altre shell relativamente recenti che vivono /bin/sh, ma la situazione è più sfumata quando vuoi supportare vecchie shell / sistemi.
mtraceur,

2
@StephenKitt Certo. Esiste una paginaset -e molto approfondita che documenta i diversi comportamenti delle conchiglie di Sven Mascheck , sebbene questa pagina documenti anche molte conchiglie storiche / antiche irrilevanti oggi. Ci sono anche queste due pagine con un focus moderno più ristretto (ricerca di "set -e"): pagina "lintsh" , documentazione della shell portatile di autoconf -> sottopagina Limitation of Builtins
mtraceur

32

Sebbene non influisca sull'output del programma appena eseguito, consente al chiamante di procedere come se tutto andasse bene, ovvero influisce sulla logica futura.

Sostituito: maschera lo stato di errore del comando precedente.

michael@x071:[/usr/sbin]cat /tmp/false.sh
#!/bin/sh
false

michael@x071:[/usr/sbin]cat /tmp/true.sh 
#!/bin/sh
false || true

michael@x071:[/usr/sbin]sh /tmp/false.sh; echo $?
1
michael@x071:[/usr/sbin]sh /tmp/true.sh; echo $? 
0

6
È vero, ma non risponde al motivo per cui è utile mascherare lo stato di uscita di un comando.
Moopet,

4
set -e significa che lo script terminerà immediatamente con un ritorno diverso da zero. Potresti, in quel punto localizzato, non desiderare che ciò accada!
rackandboneman,

Sono una persona semplice - e per me l'unica ragione per mascherare lo stato di errore è perché è "sulla strada". set -e commette errori "nel modo" se prima non ti importava. Mi piace la discussione perché la vedo come un buon modo per aiutarmi a eseguire il debug dei miei script e scrivere una logica aggiuntiva per rispondere a un errore (ad esempio, || print - "qui esisteva zero diverso da zero". Molto probabilmente anche se ho un funzione di shell "fatale" e ho "qualcosa di || fatale" infelice me ". Imho uno script dovrebbe riportare uno stato fallito, o non importa. -e più || vero è mascherare errori. Se questo è quello che voglio - bene, in caso contrario, mi mancano errori
Michael Felt,

quello che devo chiedermi è: è || true - una stampella codificante (un modo pigro per aggirare / superare un errore che non voglio affrontare ora; uno strumento di debug (-e ma no || true) o solo il dogma di qualcuno su quale sia la buona pratica di codifica. In altre parole - Lo vedo come una caratteristica - con un potenziale beneficio. Non lo vedo come una bacchetta magica per curare tutto. In breve - proprio come la bellezza è negli occhi di chi guarda - set -ee l' || trueutilità sarà definita dai tratti e dagli obiettivi di il programmatore
Michael Felt,

6
@MichaelFelt Considerare: git remote remove foo || true git remote add foo http://blah- vogliamo ignorare l'errore se il telecomando non esiste.
user253751
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.