2009-02-21 7 views
6

In uno script bash, devo verificare l'esistenza di diversi file.Bash: come faccio a verificare se alcuni file esistono?

so un modo scomodo per farlo, che è la seguente, ma ciò significherebbe che il mio programma principale deve essere all'interno di quella brutta struttura annidata:

if [ -f $FILE1 ] 
then 
if [ -f $FILE2 ] 
then 
    echo OK 
    # MAIN PROGRAM HERE 
fi 
fi 

La seguente versione non funziona:

([ -f $FILE1 ] && [ -f $FILE2 ]) || (echo "NOT FOUND"; exit 1) 
echo OK 

Esso stampa

NOT FOUND 
OK 

c'è un modo elegante per fare questo diritto?

AGGIORNAMENTO: Vedere la risposta accettata. Inoltre, in termini di eleganza Mi piace Jonathan Leffler's answer:

arg0=$(basename $0 .sh) 
error() 
{ 
    echo "$arg0: [email protected]" 1>&2 
    exit 1 
} 

[ -f $FILE2 ] || error "$FILE2 not found" 
[ -f $FILE1 ] || error "$FILE1 not found" 

risposta

10

Come su

if [[ ! (-f $FILE1 && -f $FILE2) ]]; then 
    echo NOT FOUND 
    exit 1 
fi 

# do stuff 
echo OK 

Vedere help [[ e help test per le opzioni utilizzabili con i test in stile [[. Leggi anche this faq entry.

La tua versione non funziona perché (...) genera una nuova sotto-shell, in cui viene eseguito il exit. Quindi, riguarda solo quella subshell, ma non lo script in esecuzione.

Il seguente funziona, invece, eseguendo i comandi tra {...} nella shell corrente.

Si noti inoltre che è necessario citare entrambe le variabili per assicurarsi che non vi siano espansioni indesiderate o suddivisione in parole (devono essere passate come argomento a [).

[ -f "$FILE1" ] && [ -f "$FILE2" ] || { echo "NOT FOUND"; exit 1; } 
+0

Grazie, sembra buono. Solo il 'o' (||) dovrebbe essere un 'e' (&&), immagino. – Frank

+0

già risolto :) difficile con la logica di sera :) –

4

Penso che stai cercando:

if [ -f $FILE1 -a -f $FILE2 ]; then 
    echo OK 
fi 

Vedere man test per maggiori dettagli su ciò che si può mettere dentro la [ ].

+0

+1 per 'man test'. Grazie! – binarybob

3

È possibile elencare i file e il check-in un ciclo:

file_list='file1 file2 wild*' 
for file in $file_list; do 
    [ -f $file ] || exit 
done 

do_main_stuff 
1

Io di solito utilizzare una variante:

arg0=$(basename $0 .sh) 
error() 
{ 
    echo "$arg0: [email protected]" 1>&2 
    exit 1 
} 

[ -f $FILE2 ] || error "$FILE2 not found" 
[ -f $FILE1 ] || error "$FILE1 not found" 

Non c'è virtù particolare nel rendere lo script di shell avere una singola uscita punto - nessun danno, ma errori fatali possono anche terminare la sceneggiatura.

L'unico punto di discussione sarebbe se diagnosticare quanti più problemi possibili prima di uscire, o se solo diagnosticare il primo. In media, diagnosticare solo il primo è molto più facile.