web-dev-qa-db-fra.com

Script Bash: teste le répertoire vide

Je veux tester si un répertoire ne contient aucun fichier. Si tel est le cas, je vais ignorer certains traitements.

J'ai essayé ce qui suit:

if [ ./* == "./*" ]; then
    echo "No new file"
    exit 1
fi

Cela donne l'erreur suivante:

line 1: [: too many arguments

Y a-t-il une solution/alternative?

85
Anthony Kong
if [ -z "$(ls -A /path/to/dir)" ]; then
   echo "Empty"
else
   echo "Not Empty"
fi

En outre, il serait intéressant de vérifier si le répertoire existe avant.

111
Andrey Atapin
if [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
    echo "Empty directory"
else
    echo "Not empty or NOT a directory"
fi
17
uzsolt

Pas besoin de compter quoi que ce soit ou de globes Shell. Vous pouvez également utiliser read en combinaison avec find. Si la sortie de find est vide, vous retournerez false:

if find /some/dir -mindepth 1 | read; then
   echo "dir not empty"
else
   echo "dir empty"
fi

Cela devrait être portable.

17
slhck
#!/bin/bash
if [ -d /path/to/dir ]; then
    # the directory exists
    [ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
    # You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi
12
Renaud

Cela fera le travail dans le répertoire de travail courant (.):

[ `ls -1A . | wc -l` -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."

ou la même commande divisée sur trois lignes juste pour être plus lisible:

[ `ls -1A . | wc -l` -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."

Il suffit de remplacer ls -1A . | wc -l par ls -1A <target-directory> | wc -l si vous devez l'exécuter sur un autre dossier cible.

Edit : J'ai remplacé -1a par -1A (voir le commentaire @Daniel)

4
ztank1013

Utilisez le suivant:

count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
   echo "No new file"
   exit 1
fi

De cette façon, vous êtes indépendant du format de sortie de ls. -mindepth ignore le répertoire lui-même, -maxdepth empêche la défense récursive dans des sous-répertoires pour accélérer les choses.

3
Daniel Beck

Un hacky, mais uniquement bash, sans PID:

is_empty() {
    test -e "$1/"* 2>/dev/null
    case $? in
        1)   return 0 ;;
        *)   return 1 ;;
    esac
}

Ceci tire parti du fait que test construit se termine avec 2 si plus d'un argument est donné après -e: D'abord, "$1"/* glob est développé par bash. Cela se traduit par un argument par fichier. Alors

  • S'il n'y a aucun fichier, l'astérisque dans test -e "$1"* ne se développe pas, donc Shell retourne à l'essai du fichier nommé *, qui renvoie 1.

  • ... sauf s'il y a réellement un fichier nommé exactement *, l'astérisque se développe alors, astérisque, qui aboutit au même appel que ci-dessus, c'est-à-dire. test -e "dir/*", cette fois, retourne 0. (Merci @TrueY pour l'avoir signalé.)

  • S'il y a un fichier, test -e "dir/file" est exécuté, ce qui renvoie 0.

  • Mais s'il y a plus de fichiers que 1, test -e "dir/file1" "dir/file2" est exécuté, ce qui est signalé par bash comme une erreur d'utilisation, c'est-à-dire 2.

case encapsule toute la logique pour que seul le premier cas, avec 1 état de sortie, soit signalé comme ayant abouti.

Problèmes possibles que je n'ai pas vérifiés:

  • Il y a plus de fichiers que le nombre d'arguments autorisés - je suppose que cela pourrait se comporter de la même manière que le cas de 2 fichiers ou plus.

  • Ou alors il y a un fichier avec un nom vide - je ne suis pas sûr que ce soit possible avec n'importe quel système d'exploitation/système d'exploitation.

3
Alois Mahdal

Utiliser un tableau:

files=( * .* )
if (( ${#files[@]} == 2 )); then
    # contents of files array is (. ..)
    echo dir is empty
fi
3
glenn jackman

Avec FIND (1) (sous Linux et FreeBSD), vous pouvez regarder de manière non récursive une entrée de répertoire via "-maxdepth 0" et tester si elle est vide avec "-empty". Appliqué à la question cela donne:

if test -n "$(find ./ -maxdepth 0 -empty)" ; then
    echo "No new file"
    exit 1
fi
2
TimJ
if find "${DIR}" -Prune ! -empty -exit 1; then
    echo Empty
else
    echo Not Empty
fi

EDIT: Je pense que cette solution fonctionne bien avec gnu find, après un quick regardez le implementation . Mais cela peut ne pas fonctionner avec, par exemple, recherche de netbsd . En effet, celui-ci utilise le champ st_size de stat (2). Le manuel le décrit comme:

st_size            The size of the file in bytes.  The meaning of the size
                   reported for a directory is file system dependent.
                   Some file systems (e.g. FFS) return the total size used
                   for the directory metadata, possibly including free
                   slots; others (notably ZFS) return the number of
                   entries in the directory.  Some may also return other
                   things or always report zero.

Une meilleure solution, également plus simple, est:

if find "${DIR}" -mindepth 1 -exit 1; then
    echo Empty
else
    echo Not Empty
fi

De plus, la solution -Prune dans la 1ère est inutile.

EDIT: no -exit for gnu find .. la solution ci-dessus est bonne pour la recherche de NetBSD. Pour GNU find, cela devrait fonctionner:

if [ -z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`" ]; then
    echo Empty
else
    echo Not Empty
fi
1
yarl

Je pense que la meilleure solution est:

files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty" 

grâce à https://stackoverflow.com/a/91558/520567

Ceci est une édition anonyme de ma réponse qui pourrait être utile ou non à quelqu'un: Une légère modification indique le nombre de fichiers

files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]}) 
echo "MYPATH contains $files files"

Cela fonctionnera correctement même si les noms de fichiers contiennent des espaces.

1
akostadinov

Qu'en est-il de tester si le répertoire existe et non vide dans une instruction if

if [[ -d path/to/dir && -n "$(ls -A path/to/dir)" ]]; then 
  echo "directory exists"
else
  echo "directory doesn't exist"
fi
0
stanieviv

Tout cela est génial - il suffit d’en faire un script pour que je puisse rechercher des répertoires vides sous le répertoire actuel. Le fichier ci-dessous devrait être placé dans un fichier appelé 'findempty', placé quelque part dans le chemin afin que bash puisse le trouver, puis exécuter chmod 755. Peut facilement être adapté à vos besoins spécifiques, je suppose.

#!/bin/bash
if [ "$#" == "0" ]; then 
find . -maxdepth 1 -type d -exec findempty "{}"  \;
exit
fi

COUNT=`ls -1A "$*" | wc -l`
if [ "$COUNT" == "0" ]; then 
echo "$* : $COUNT"
fi
0
Warren Sherliker

Ce travail pour moi, pour vérifier et traiter les fichiers dans le répertoire ../IN, en considérant que le script est dans le répertoire ../Script:

FileTotalCount=0

    for file in ../IN/*; do
    FileTotalCount=`expr $FileTotalCount + 1`
done

if test "$file" = "../IN/*"
then

    echo "EXITING: NO files available for processing in ../IN directory. "
    exit

else

  echo "Starting Process: Found ""$FileTotalCount"" files in ../IN directory for processing."

# Rest of the Code
0
Arijit