How do I check whether a directory is empty or not under Linux / UNIX using a shell script? I'd like to take some action if directory is empty.
There are many ways to find out if a directory is empty or not under UNIX / Linux bash shell. You can use the find command to list only files. In this example, find command will only print file name from /tmp. If there is no output, directory is empty.
$ find "/tmp" -type f -exec echo Found file {} \;
Output:
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
You should follow me on twitter here or grab rss feed to keep track of new changes.
Featured Articles:
- 30 Handy Bash Shell Aliases For Linux / Unix / Mac OS X
- Top 30 Nmap Command Examples For Sys/Network Admins
- 25 PHP Security Best Practices For Sys Admins
- 20 Linux System Monitoring Tools Every SysAdmin Should Know
- 20 Linux Server Hardening Security Tips
- Linux: 20 Iptables Examples For New SysAdmins
- Top 20 OpenSSH Server Best Security Practices
- Top 20 Nginx WebServer Best Security Practices
- 20 Examples: Make Sure Unix / Linux Configuration Files Are Free From Syntax Errors
- 15 Greatest Open Source Terminal Applications Of 2012

- My 10 UNIX Command Line Mistakes
- Top 10 Open Source Web-Based Project Management Software
- Top 5 Email Client For Linux, Mac OS X, and Windows Users
- The Novice Guide To Buying A Linux Laptop












{ 28 comments… read them below or add one }
Seems to me that using ls is not required – in fact, it is doable within the shell alone:
set - `echo .* *`if [ $# = "2" ] ; then
: empty directory
else
: not empty ...
fi
David
UNIX Administratosphere
David,
It is not working for me. I’m using Debian + Bash 3. It returns 3 when directory is empty, it should be 2 as empty directory has only . and ..
Any idea?
Yes. I’d forgotten: when no matches are found (“*”) then the resulting text is the character unchanged. This should work better:
FILES=”`echo .* *`”
if [ $FILES = '. .. *' ] ; then
: empty dir
else
: not empty
fi
find -type d -emptyThanks Scot!
Scot’s suggestion works absolutely perfectly.
A slight variation on the original post which does it numerically and includes dot files.
That’s a one and not an ‘l’ to the ls command. An empty directory only has the two entries – . & ..
Works with both BSD and GNU Linux find:
find "/nas/data" -maxdepth 0 -empty -exec echo {} is empty. \;OR
find "/dir2" type d -empty -exec command1 -arg1 {} \;I am trying to pass a directory path as a parameter to my bash script (which tests whether its empty), but the directory name contains spaces. Any suggestions?
enclose the directory name parameter in double quotes.
The following code does not correctly identify empty directories. Using DIR=$1 then passing “home/dan/not empty” does not help, neither does using “home/dan/not\ empty” or home/dan/not\ empty.
#!/bin/bash
DIR=”home/dan/not empty”
if [ "$(ls -A $DIR)" ]; then
echo “$DIR is not empty”
else
echo “$DIR is empty”
fi
Replace
if [ "$(ls -A $DIR)" ]; then
with
if [ "$(ls -A "$DIR")" ]; then
That’s just another pair of quotes, no escapes. Should work.
dude. give find some love ;-)
find . -type d -empty -exec touch {}/.empty \;
find “/dir2″ -type d -empty -exec command1 -arg1 {} \;
if [ "$(ls -A $DIR)" ]; then
How can I use this expression exclude one directory?
what if the directory has files but each file is of 0 size?
best way is to do as below:
dir_full_path=”/tmp/foo”
if [ -d "$dir_full_path" ] ; then
if [ 4 -ge $(du -s "$dir_full_path" ] ; then
echo “empty directory $dir_full_path”
else
echo “non-empty directory $dir_full_path”
fi
fi
This snippet assumes that a directory size, by its own name, is always 4096 bytes, approximated to 4.0K evaluated to int as 4
Hi all,
someone please say me why this dont work.
src=”/Users/xxxx/scripts/dirtest”
for dir in `ls -R “$src”`
do
if [ -d "$dir" ]; then
echo this is a dir: $dir
fi
done
thanks
Jairo :
Declare the variable ,before you use it.
Ok, this works, after hours of coding a simple solution was found to be best loll.What kept giving me trouble was the *, also I had found a solution a long time ago, but it didnt work if you had empty files in the directory.I tried all the IF statement solutions and it wont work in all situations.So best method is below:
#!/bin/bash
DIR=/var/www/tee
for i in $DIR/*
do
if [ -e $i ] && [ $(echo $?) -eq "0 " ]
then
echo The Directory is NOT EMPTY
else
echo The directory is EMPTY
fi
done
Very good Vivek. Cool.
if [ $( stat -c %h . ) -gt 2 ] ; then echo not empty; fi
Solution with “$(ls -A $DIR)” could exceed command buffer size.
Square brackets are only needed with if when you’re using test expressions, and by doing away with them you can do away with the process substitution. You can test the exit status of a program or command just by running it. (Getting ls to give an error code in this case requires a slight change in syntax.)
if ! ls -A $DIR/* > /dev/null 2>&1; then echo "Take action $DIR is not Empty" else echo "$DIR is Empty" fialternately,
if ls -A $DIR/* > /dev/null 2>&1; then echo "$DIR is Empty" else echo "Take action $DIR is not Empty" fiIf used in a script, I’d go with a slight modification of the first comment (as the “set” clobbers positional parameters, putting it in a function will clobber only local function parameters, not the global ones!):
shopt -s dotglob nullglob is_empty_dir() { set - "`echo $1/*`" test -z "$1" }And then calling:
why not using simple :
if [ ! -f /folder/* ]; then
echo “folder not empty”
else
echo “folder empty”
fi
I had a seriously nasty time with this.
In a bash script I wanted to:
1. Create and pass a list of directories that match a pattern
2. Use a variable to check if the directories matching the pattern were empty
3. Delete empty directories.
The challenge I ran into was with wildcard expansion in variables. I spent a little while pulling my hair out over ” and ‘ and ` until I figured out (the final solution was pretty simple).
Here is my short script that
1. creates a list of directories within $1 that match a pattern
– in this case the grep returns all directories that are 5 numerical digits
2. verifies whether or not content exists
3. deletes the directory if no content is present
#!/bin/bash
# List Empty Directories that are directories in the
# format ./##### If they are empty, delete them.
ls -d */ > testdir.txt
grep ‘[0-9]\{5\}’ ./testdir.txt > testdir2.txt
rm ./testdir.txt
i=1
while [ $i -le `wc -l ./testdir2.txt | gawk '{print $1}'` ]; do
line=`head -$i ./testdir2.txt | tail -1`
correctdirname=”./”$line
echo -n “Dir “$i” “$correctdirname
files=`echo $correctdirname $correctdirname*`
test=$correctdirname” “$correctdirname”*”
if [ "$files" == "$test" ]
then echo ” empty” #; rm -rf $correctdirname
else echo ” files found”
fi
i=`expr $i + 1`
done
For safety I commented out the delete/rm. Anyone trying this should test carefully before running this script and use a test directory with test data. The delete command will delete entire directories whether they are empty or not! Verify your scenario, verify the variables match your scenario, and double-check before uncommenting that rm command.
I hope someone finds this useful.
Minor correction:
I mistakenly said “1. creates a list of directories within $1 that match a pattern”
It should read “1. creates a list of directories within the current directory that match a pattern”
Also I didn’t remove testdir2.txt, created by the script in the current directory. A line to remove that could be added after the “done” to clean up the 2nd temporary file created by the script.
After having solved the logic problem I was overly-focused on I was playing around with additional information from the above posts and changed my if statment based upon the one provided by nixcraft, above:
My if original: if [ "$files" == "$test" ]
Nixcraft’s if: if [ "$(ls -A $DIR)" ]
My new if: if [ ! "$(ls -A $line)" ]
Using the if provided by Nixcraft I came up with an if that works in place of the if statement in my above script and is a little cleaner because it does not require creation of the $test variable. I put a ! in front of it so I could easily swap if statements. Alternately you could reverse the then-else.
Here is the updated script with the old vars and if commented out:
#!/bin/bash
# List Empty Directories that are directories in the
# format ./##### If they are empty, delete them.
ls -d */ > testdir.txt
grep ‘[0-9]\{5\}’ ./testdir.txt > testdir2.txt
rm ./testdir.txt
i=1
while [ $i -le `wc -l ./testdir2.txt | gawk '{print $1}'` ]; do
line=`head -$i ./testdir2.txt | tail -1`
correctdirname=”./”$line
echo -n “Dir “$i” “$correctdirname
# files=`echo $correctdirname $correctdirname*`
# test=$correctdirname” “$correctdirname”*”
# if [ "$files" == "$test" ]
if [ ! "$(ls -A $line)" ]
then echo ” empty” #; rm -rf $correctdirname
else echo ” files found”
fi
i=`expr $i + 1`
done
rm ./testdir2.txt
Note I added the final line to remove the 2nd test/data file.
Also you should be able to comment out the if and uncomment the 3 lines above it to switch back and forth between the two options.
This is why I don’t post often. I keep finding mistakes. I don’t know how other posters do it–such simple elegant posts that are correct.
Upon further inspection I realized my if statement, while it works in my bash, is using the wrong variable. I created the $correctdirname variable because grepping directories gave me ##### rather than ./#####.
if [ ! "$(ls -A $line)" ]
I believe you should be using $correctdirname for the reason above even though the script works for me–I don’t know if it will work generically given the difference.
The “more-correct” if-statement:
if [ ! "$(ls -A $correctdirname)" ]