Bash Shell Check Whether a Directory is Empty or Not

How do I check whether a directory is empty or not under Linux / UNIX using a shell script? I would like to take some action if directory is empty on a Linux or Unix like system. How can I check from bash/ksh shell script if a directory contains files? How do I check whether a directory is empty or not?

There are many ways to find out if a directory is empty or not under Linux and Unix bash shell. You can use the find command to list only files. [donotprint][/donotprint]In this example, find command will only print file name from /tmp. If there is no output, directory is empty.

Check whether a directory is empty or not using find command

The basic syntax is as follows:

find /dir/name -type -f -exec command {} ;

OR GNU/BSD find command syntax:

find /path/to/dir -maxdepth 0 -empty -exec echo {} is empty. ;

OR

find /path/to/dir -type d -empty -exec command1 arg1 {} ;
In this example, check whether a directory called /tmp/ is empty or not, type:
$ find "/tmp" -type f -exec echo Found file {} ;
Sample outputs:

Found file /tmp/_.c
Found file /tmp/orbit-vivek/bonobo-activation-server-ior
Found file /tmp/orbit-vivek/bonobo-activation-register.lock
Found file /tmp/_.vsl
Found file /tmp/.X0-lock
Found file /tmp/.wine-1000/server-802-35437d/lock
Found file /tmp/.wine-1000/cxoffice-wine.lock
Found file /tmp/ksocket-vivek/Arts_PlayObjectFactory
Found file /tmp/ksocket-vivek/Arts_SimpleSoundServer
Found file /tmp/ksocket-vivek/secret-cookie
Found file /tmp/ksocket-vivek/Arts_AudioManager
Found file /tmp/ksocket-vivek/Arts_SoundServer
Found file /tmp/ksocket-vivek/Arts_SoundServerV2
Found file /tmp/vcl.XXf8tgOA
Found file /tmp/Tracker-vivek.6126/cache.db
Found file /tmp/gconfd-vivek/lock/ior

However, the simplest and most effective way is to use ls command with -A option:
$ [ "$(ls -A /path/to/directory)" ] && echo "Not Empty" || echo "Empty"
or
$ [ "$(ls -A /tmp)" ] && echo "Not Empty" || echo "Empty"
You can use if..else.fi in a shell script:

#!/bin/bash
FILE=""
DIR="/tmp"
# init
# look for empty dir 
if [ "$(ls -A $DIR)" ]; then
     echo "Take action $DIR is not Empty"
else
    echo "$DIR is Empty"
fi
# rest of the logic

#!/bin/bash
FILE=""
DIR="/tmp"
# init
# look for empty dir
if [ "$(ls -A $DIR)" ]; then
echo "Take action $DIR is not Empty"
else
echo "$DIR is Empty"
fi
# rest of the logic

Here is another example using bash for loop to check for any *.c files in the ~/projects/ directory:

# Bourne/bash for loop example 
for z in ~/projects/*.c; do
        test -f "$z" || continue
        echo "Working on $z C program..."
done

# Bourne/bash for loop example
for z in ~/projects/*.c; do
test -f "$z" || continue
echo "Working on $z C program…"
done

Check if folder /data/ is empty or not using bash only features

From the Linux and Unix bash(1) man page:

  • nullglob If set, bash allows patterns which match no files to expand to a null string, rather than themselves.
  • dotglob – If set, bash includes filenames beginning with a . in the results of pathname expansion.
#!/bin/bash
# Set the variable for bash behavior
shopt -s nullglob
shopt -s dotglob
 
# Die if dir name provided on command line
[[ $# -eq 0 ]] && { echo "Usage: $0 dir-name"; exit 1; }
 
# Check for empty files using arrays 
chk_files=(${1}/*)
(( ${#chk_files[*]} )) && echo "Files found in $1 directory." || echo "Directory $1 is empty."
 
# Unset the variable  for bash behavior
shopt -u nullglob
shopt -u dotglob

#!/bin/bash
# Set the variable for bash behavior
shopt -s nullglob
shopt -s dotglob # Die if dir name provided on command line
[[ $# -eq 0 ]] && { echo "Usage: $0 dir-name"; exit 1; } # Check for empty files using arrays
chk_files=(${1}/*)
(( ${#chk_files[*]} )) && echo "Files found in $1 directory." || echo "Directory $1 is empty." # Unset the variable for bash behavior
shopt -u nullglob
shopt -u dotglob

Sample outputs:

$ ./script.sh /tmp
Files found in /tmp directory.
$ mkdir /tmp/foo
$ ./script.sh /tmp/foo
Directory /tmp/foo/ is empty.

A note about ksh user

Try for loop as follows:

## In ksh93, prefix ~(N) in front of the pattern
## For example, find out if *.mp4 file exits or not in a dir
cd $HOME/Downloads/music/
for f in ~(N)*.mp4; do
        # do something if file found
        echo "Working on $f..."
done

## In ksh93, prefix ~(N) in front of the pattern
## For example, find out if *.mp4 file exits or not in a dir
cd $HOME/Downloads/music/
for f in ~(N)*.mp4; do
# do something if file found
echo "Working on $f…"
done

Posted by: SXI ADMIN

The author is the creator of SXI LLC and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.