views:

1830

answers:

11

How do I check if a directory contains files?

Something similar to this:

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

but which works if the directory contains one or several files (the above one only works with exactly 0 or 1 files).

+4  A: 

Try:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
Greg Hewgill
A: 
DIR="/some/dir"
if["$(ls -A $DIR)"]; then
     echo 'Theres something alive in here';
fi
Andrew Taylor
+1  A: 

Could you compare the output of this?

 ls -A /some/dir | wc -l
DGM
+1  A: 
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
Toby
I like this one as there are no quotes or brackets crufting up the command.
Dave Webb
+2  A: 

The solutions so far use ls. Here's an all bash solution:

shopt -s nullglob
shopt -s dotglob # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
Bruno De Fraine
as long as you remember to set the options back to their original value at the end of the script :)
Jean
A: 

I was sort of hoping there was some way not to do an ls and count rows and whatnot, but it seems necessary. By piecing together bits from the above, this seems to do what I want:

if [ ! -z "$(ls /some/dir/)" ]; then echo "huzzah"; fi

I could do ls -A just as well, but any hidden file will just be left in place. I don't expect to get any, and if I do, I don't want them.

ionn
+2  A: 

How about the following:

if find /some/dir/ -maxdepth 0 -empty | read; then echo "huzzah"; fi

This way there is no need for generating a complete listing of the contents of the directory. The read is both to discard the output and make the expression evaluate to true only when something is read (i.e. /some/dir/ is found empty by find).

mweerden
A: 

Take care with directories with a lot of files! It could take a some time to evaluate the "ls" command.

IMO the best solution is the one that uses "find /some/dir/ -maxdepth 0 -empty"

Gravstar
+1  A: 

You can count the number of hard links a directory has, using the stat command. If the number is greater than 2 (. and .. are always present), you have files in a directory.

if [ `stat -c "%h" $dir` -gt 2 ]; then echo "huzzah"; fi

This should have the advantage of being instant even if the directory contains large amounts of files.

Steve Baker
A: 

This may be a really late response but here is a solution that works. This line only recognizes th existance of files! It will not give you a false positive if directories exist.

if find /path/to/check/* -maxdepth 0 -type f | read; then echo "Files Exist"; fi

A: 
# Checks whether a directory contains any nonhidden files.
#
# usage: if isempty "$HOME"; then echo "Welcome home"; fi
#
isempty() {
    for _ief in $1/*; do
        if [ -e "$_ief" ]; then
            return 1
        fi
    done
    return 0
}

Some implementation notes:

  • The for loop avoids a call to an external ls process. It still reads all the directory entries once. This can only be optimized away by writing a C program that uses readdir() explicitly.
  • The test -e inside the loop catches the case of an empty directory, in which case the variable _ief would be assigned the value "somedir/*". Only if that file exists will the function return "nonempty"
  • This function will work in all POSIX implementations. But be aware that the Solaris /bin/sh doesn't fall into that category. Its test implementation doesn't support the -e flag.
Roland Illig