开发者

How to test if a directory is empty with find

I am trying to write an if statement in a unix shell script that returns true if it's empty, and false if it's not.

This type of thing...

if directory foo is empty then
echo empty
else
echo not empty
fi

How do I do this? I'm told find is a good palce to s开发者_StackOverflowtart


Simple - use the -empty flag. Quoting the find man page:

 -empty  True if the current file or directory is empty.

So something like:

find . -type d -empty

Will list all the empty directories.


Three best answers:

  1. The first one is based on find as OP requested ;
  2. The second is based on ls ;
  3. The third one is 100% bash but it invokes (spawns) a sub-shell.

1. [ $(find your/dir -prune -empty) = your/dir ]

dn=your/dir
if [ x$(find "$dn" -prune -empty) = x"$dn" ]; then
  echo empty
else
  echo not empty
fi

test:

> mkdir -v empty1 empty2 not_empty
mkdir: created directory 'empty1'
mkdir: created directory 'empty2'
mkdir: created directory 'not_empty'
> touch not_empty/file
> find empty1 empty2 not_empty -prune -empty
empty1
empty2

find has printed the two empty directories only (empty1 and empty2).

This answer looks like the -maxdepth 0 -empty from Ariel. But this answer is a bit shorter ;)

2. [ $(ls -A your/directory) ]

if [ "$(ls -A your/dir)" ]; then
  echo not empty
else
  echo empty
fi

or

[ "$(ls -A your/dir)" ] && echo not empty || echo empty

Similar to Michael Berkowski and gpojd answers. But here we do not require to pipe to wc. See also Bash Shell Check Whether a Directory is Empty or Not by nixCraft (2007).

3. (( ${#files} ))

files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} )); then 
  echo not empty
else 
  echo empty or does not exist
fi

Caution: as written in this above example, there is no difference between an empty directory and a non-existing one.

This last answer has been inspired from the Bruno De Fraine's answer and the excellent comments from teambob.


There must be an easier way, but you can test for an empty/nonempty directory with ls -1A piped to wc -l

DIRCOUNT=$(ls -1A /path/to/dir |wc -l)
if [ $DIRCOUNT -eq 0 ]; then
  # it's empty
fi


find directoryname -maxdepth 0 -empty


Why do you have to use find? In bash, ls -a will return two files (. and ..) for an empty directory and should have more than that for non-empty ones.

if [ $(ls -a | wc -l) -eq 2 ]; then echo "empty"; else echo "not empty"; fi


if [ `find foo | wc -l` -eq 1 ]
then
    echo Empty
else
    echo Not empty
fi

foo is the directory name here.


Something like below

dircnt.sh:
-----------
#!/bin/sh

if [ `ls $1 2> /dev/null | wc -l` -gt 0 ]; then echo true; else echo false; fi

Usage

andreas@earl ~
$ mkdir asal

andreas@earl ~
$ sh dircnt.sh asal
false

andreas@earl ~
$ touch asal/1

andreas@earl ~
$ sh dircnt.sh asal
true


I don't like using ls because I have some very large directories and I hate wasting the resources to fill a pipe with all that stuff.

I don't like filling a $files variable with all that stuff either.

So while all of @libre's answers are interesting, I find them all unreadable, and prefer to make a function of my favorite, the 'find' solution:

function isEmptyDir {
  [ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}

So that I can write code that I can read a year from now without asking "what was I thinking"?

if isEmptyDir some/directory
then
  echo "some/directory is empty"
else
  echo "some/directory does not exist, is not a directory, or is empty
fi

or I can use additional code to tease apart the negative results, but that code should be pretty obvious. In any case, I'll know right away what I was thinking.


NO script, no fork/exec (echo is a builtin)...

[ "$(cd $dir;echo *)" = "*" ] && echo empty || echo non-empty
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜