2009-08-21 4 views
3

Je veux vérifier si un répertoire contient des fichiers ou non dans bash. Mon code est ici.Comment tester le résultat de l'extension du nom de fichier en bash?

for d in {,/usr/local}/etc/bash_completion.d ~/.bash/completion.d 
    do    
     [ -d "$d" ] && [ -n "${d}/*" ] &&       

     for f in $d/*; do                           
      [ -f "$f" ] && echo "$f" && . "$f"       

     done                               
    done 

Le problème est que "~/.bash/completion.d" n'a pas de fichier. Donc, $ d/* est considéré comme une simple chaîne "~/.bash/completion.d/*", pas une chaîne vide qui est le résultat de l'expansion du nom de fichier. En conséquence de ce code, bash essaie d'exécuter

. "~/.bash/completion.d/*" 

et bien sûr, il génère un message d'erreur.

Quelqu'un peut-il m'aider?

+0

En un mot simple, je veux savoir comment forcer l'extension de nom de fichier pour la chaîne de nom de fichier invalide – user159087

Répondre

6

Si vous définissez l'option bash nullglob, par

shopt -s nullglob 

englobement puis chutera modèles qui ne correspondent à aucun fichier.

+0

Le code de kjshim semble fonctionner pour moi, sans définir 'nullglob' (' shopt nullglob' renvoie "off"). Des idées pour lesquelles cela pourrait être? –

+0

Peut-être que les répertoires que vous avez essayés n'étaient pas vides? –

+0

'ls -la test' montre' .' et '..' –

0

Vous pouvez utiliser find directement de la manière suivante:

for f in $(find {,/usr/local}/etc/bash_completion.d ~/.bash/completion.d -maxdepth 1 -type f); 
do echo $f; . $f; 
done 

Mais find imprime un avertissement si une partie du répertoire ne se trouve pas, vous pouvez mettre un 2> /dev/null ou mettre l'appel find après le test si les répertoires existent (comme dans votre code).

0
find() { 
for files in "$1"/*;do 
    if [ -d "$files" ];then 
     numfile=$(ls $files|wc -l) 
     if [ "$numfile" -eq 0 ];then 
      echo "dir: $files has no files" 
      continue 
     fi 
     recurse "$files" 
    elif [ -f "$files" ];then 
     echo "file: $files"; 
     : 
    fi 
done 
} 
find /path 
+0

Joli code. Qu'est ce que ça fait? –

0

Une autre approche

# prelim stuff to set up d 
files=`/bin/ls $d` 
if [ ${#files} -eq 0 ] 
then 
    echo "No files were found" 
else 
    # do processing 
fi 
4
 
# NOTE: using only bash builtins 
# Assuming $d contains directory path 

shopt -s nullglob 

# Assign matching files to array 
files=("$d"/*) 

if [ ${#files[@]} -eq 0 ]; then 
    echo 'No files found.' 
else 
    # Whatever 
fi 

L'affectation à un tableau a d'autres avantages, y compris la manipulation souhaitable (correct!) Des noms de fichiers/chemins contenant l'espace blanc et simple itération sans utiliser un sous -shell, comme le code suivant fait:

 
find "$d" -type f | 
while read; do 
    # Process $REPLY 
done 

au lieu de cela, vous pouvez utiliser:

 
for file in "${files[@]}"; do 
    # Process $file 
done 

avec l'avantage que la boucle est exécutée par la coque principale, ce qui signifie que les effets secondaires (tels que l'affectation de variable, par exemple) fait dans la boucle sont visibles pour le reste du script. Bien sûr, il est également façon plus rapide, si les performances sont un problème.
Enfin, un tableau peut également être inséré dans les arguments de ligne de commande (sans arguments de séparation contenant l'espace blanc):

 
$ md5sum fileA "${files[@]}" fileZ 

Vous devez toujours essayer de gérer correctement les fichiers/chemins contenant l'espace blanc, parce qu'un jour , ils vont arriver!

+0

Bravo pour le bel exemple d'expansion de glob pour les fichiers, le manuel bash est très déroutant sur cette partie! –

Questions connexes