2009-02-21 7 views
6

Dans un script bash, je dois vérifier l'existence de plusieurs fichiers.Bash: Comment vérifier si certains fichiers existent?

Je sais une façon maladroite de le faire, ce qui est la suivante, mais cela voudrait dire que mon programme principal doit être au sein de cette structure imbriquée laid:

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

La version suivante ne fonctionne pas:

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

Il imprime

NOT FOUND 
OK 

y at-il une façon élégante de faire de ce droit?

MISE À JOUR: Voir la réponse acceptée. De plus, en termes d'élégance J'aime 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" 

Répondre

10

Que diriez-vous

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

# do stuff 
echo OK 

Voir help [[ et help test pour les options utilisables avec les tests de style [[. Lire également this faq entry.

Votre version ne fonctionne pas car (...) engendre un nouveau sous-shell, dans lequel le exit est exécuté. Il affecte donc uniquement ce sous-shell, mais pas le script d'exécution.

La procédure suivante fonctionne à la place, exécutant les commandes entre {...} dans le shell en cours.

Je devrais également noter que vous devez citer les deux variables pour vous assurer qu'il n'y a pas d'expansion non désirée ou de division de mots faite (elles doivent être passées comme un argument à [).

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

Merci, ça a l'air bien. Juste le 'ou' (||) devrait être un 'et' (&&), je suppose. – Frank

+0

fixe déjà :) difficile avec la logique dans la soirée :) –

4

Je pense que vous cherchez:

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

Voir man test pour plus de détails sur ce que vous pouvez mettre à l'intérieur du [ ].

+0

+1 pour «test de l'homme». Merci! – binarybob

3

Vous pouvez lister les fichiers et les vérifier dans une boucle:

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

do_main_stuff 
1

J'utilise habituellement une 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" 

Il n'y a pas d'avantage à faire le script shell une seule sortie point - pas de mal non plus, mais des erreurs fatales peuvent aussi bien mettre fin au script. Le seul point de débat serait de diagnostiquer autant de problèmes que possible avant de sortir, ou de simplement diagnostiquer le premier. En moyenne, diagnostiquer juste le premier est beaucoup plus facile.

Questions connexes