Bash conditionals: come "ed" espressioni? (se [! -z $ VAR && -e $ VAR])


281

Immagino di non essere chiaro su come fare "e" i test. Volevo assicurarmi che esistesse un argomento che funzionasse bene [ -e $VAR ], ma si scopre che stava valutando come vero anche su una stringa vuota; che non voglio.

Come li 'e' li insieme? O c'è un altro test unario che realizza ciò che voglio?

Risposte:


532
if [ ! -z "$var" ] && [ -e "$var" ]; then
      # something ...
fi

9
Questa soluzione funziona anche con shell conformi a POSIX e quindi anche in bash; tuttavia, per sfruttare appieno i "bashismi", vedi la risposta di @ paxdiablo.
mklement0

2
Molto contento di vedere questo consigliato invece dell'obsolescente -a.
Charles Duffy,

1
Ho trovato un altro eccellente e dettagliata spiegazione - stackoverflow.com/questions/3601515/...
valentt

70

Dalla bashmanpage:

[[ expression ]] - restituisce uno stato 0 o 1 a seconda della valutazione dell'espressione condizionale.

E, per le espressioni, una delle opzioni è:

expression1 && expression2- vero se entrambi expression1e expression2sono veri.

Quindi puoi andfarli insieme come segue ( -nè l'opposto di -zcosì possiamo sbarazzarci di !):

if [[ -n "$var" && -e "$var" ]] ; then
    echo "'$var' is non-empty and the file exists"
fi

Tuttavia, non penso che sia necessario in questo caso, -e xyzzyè vero se il xyzzy file esiste e può facilmente gestire stringhe vuote. Se è quello che vuoi, allora non hai davvero bisogno del controllo -znon vuoto:

pax> VAR=xyzzy
pax> if [[ -e $VAR ]] ; then echo yes ; fi
pax> VAR=/tmp
pax> if [[ -e $VAR ]] ; then echo yes ; fi
yes

In altre parole, basta usare:

if [[ -e "$var" ]] ; then
    echo "'$var' exists"
fi

1
Possiamo accorciarlo con[[ -e "$var" ]] && echo "'$var' exists"
jaypal singh

1
Sì, se si tratta di una riga (come nel mio esempio). Non lo farei se il blocco condizionale fosse molto più complesso però.
paxdiablo,

nel caso ce ne sia un solo - forse anche lungo - comando, ha senso usare questo modulo in quanto è più corto
avp

9
if [ -n "$var" -a -e "$var" ]; then
    do something ...
fi

 


10
Poiché POSIXnon definisce il comportamento di [con serie complesse di test, dovremmo evitare di utilizzare -ao -ocon [. L'ho letto qui .
jaypal singh

2
@ jaypal-singh Hai ragione, ma l'argomento ha un bashtag e non menziona POSIX, quindi inserisco questa versione che funziona sotto bashe alcune altre shell moderne.
Slava Semushin,

2
Se stai assumendo l'uso di basho di altre shell moderne, ci sono ancora meno motivi per raccomandarlo -a.
Chepner,

Anche con bash, il modo in cui questi test si comportano non è ben definito in tutti i casi d'angolo. Considerare [ "$var1" -o "$var2" ]; se var1=(e var2=), allora ciò che abbiamo è un test per stabilire se -onon è vuoto, piuttosto che se uno var1o var2non è vuoto. Questo tipo di ambiguità è l'unica ragione legittima per il x$varlinguaggio nei testcomandi moderni (cioè post-90) con citazioni corrette, e quel linguaggio deve morire in un incendio.
Charles Duffy,

4

Cita semplicemente la tua variabile:

[ -e "$VAR" ]

Questo valuta [ -e "" ]se $VARè vuoto.

La tua versione non funziona perché valuta [ -e ]. Ora in questo caso, bash controlla semplicemente se il singolo argomento ( -e) è una stringa non vuota.

Dalla manpage:

prova e [valuta le espressioni condizionali usando un insieme di regole basate sul numero di argomenti. ...

1 argomento

L'espressione è vera se e solo se l'argomento non è null.

(Inoltre, questa soluzione ha l'ulteriore vantaggio di lavorare con nomi di file contenenti spazi)


1

Ho trovato una risposta ora. Grazie per i vostri suggerimenti!

for e in ./*.cutoff.txt; do
if grep -q -E 'COX1|Cu-oxidase' $e
then
    echo xyz >$e.match.txt
else
    echo
fi

if grep -q -E 'AMO' $e
then
    echo abc >$e.match.txt
else
    echo
fi; done

Qualche commento a riguardo? Sembra inefficace fare il grep due volte, ma funziona ...

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.