In uno script bash, usando il condizionale "o" in un'istruzione "if"


129

Questa domanda è una sorta di seguito della mia domanda precedente . Gli utenti di questo sito mi hanno gentilmente aiutato a determinare come scrivere un forloop bash che scorre sui valori di stringa. Ad esempio, supponiamo che una variabile di controllo del ciclo fnamescorre le stringhe "a.txt" "b.txt" "c.txt". Vorrei echo"si!" quando fnameha il valore "a.txt"o "c.txt"e echo"no!" altrimenti. Ho provato il seguente script shell bash:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
 echo $fname
 if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
 echo "yes!"
else
 echo "no!"
fi
done

Ottengo l'output:

a.txt

no!

b.txt

no!

c.txt

sì!

Perché la ifdichiarazione sembra apparentemente vera quando fnameha il valore "a.txt"? Ho usato in |modo errato?


3
In bash, "o" operator is "||" (Stile C).
Marius Cotofana,

3
Puoi anche usare -oall'interno dello stesso [ ].
Thor,

6
@Thor Preferirei ||e separare [ ]sopra -oper la portabilità, semplicemente perché [non è garantita per supportare più di 4 argomenti. Naturalmente se la lingua di destinazione è bash, nessuno dovrebbe essere utilizzando [in ogni modo perché bash's [[è superiore in molti modi.
jw013,

2
@ jw013 Grazie. Questo significa che dovrei usare if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]]piuttosto che if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]?
Andrew,

5
@Andrew È corretto, se come stai dichiarando lo shebang bash, come stai già facendo. Uno dei vantaggi [[è che non fa la suddivisione in parole (caso speciale), quindi [[ $unquoted_var = string ]]è sicuro.
jw013,

Risposte:


229

Se vuoi dire ORusa double pipe ( ||).

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]

(Il codice OP originale utilizzato |era semplicemente il piping dell'output del lato sinistro sul lato destro, allo stesso modo in cui funziona qualsiasi normale tubo.)


4
Inoltre, ||non esegue una logica "OR" standard: cortocircuita e il secondo comando viene eseguito solo se il primo ha esito negativo.
Holdenweb,

13
@holdenweb Sono abbastanza sicuro che la maggior parte dei linguaggi ottimizzati moderni funzionano allo stesso modo. Non è necessario impiegare cicli della CPU per valutare la seconda condizione ORse la prima condizione è vera.
bahamat,

1
Pensavo che a bash piacesse, ==ma dopo aver visto questa risposta, ho deciso di cercarlo. Apparentemente, "può essere usato ma non è standard". Ho pensato di mettere questo qui per gli altri se la vostra curiosità: stackoverflow.com/a/2237103
Harperville

Questo è ciò testche raccomanda anche la pagina man
cdosborn,

2
Puoi anche utilizzare i test con doppia parentesi - if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]](se vuoi o devi avere la funzionalità aggiuntiva associata [[ ]]).
HankCa,
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.