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]
Tutorial details
Difficulty level Easy
Root privileges No
Requirements None
Est. reading time 2m
[/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. \;


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"
$ [ "$(ls -A /tmp)" ] && echo "Not Empty" || echo "Empty"
You can use in a shell script:

# init
# look for empty dir 
if [ "$(ls -A $DIR)" ]; then
     echo "Take action $DIR is not Empty"
    echo "$DIR is Empty"
# 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..."

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.
# 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[*]} )) && 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:

$ ./ /tmp
Files found in /tmp directory.
$ mkdir /tmp/foo
$ ./ /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..."

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 45 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
45 comments… add one
  • David Nov 23, 2007 @ 19:36

    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
    : not empty ...


  • Raju Nov 23, 2007 @ 21:06


    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?

  • David Nov 23, 2007 @ 21:29

    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
    : not empty

  • Scot Jan 6, 2009 @ 1:06

    find -type d -empty

    • TJRudd Nov 2, 2013 @ 13:30

      `find . -depth -type d -empty` would work a little better..

       find . -depth -type d -empty -delete
  • Tomas M May 21, 2009 @ 12:48

    Thanks Scot!

  • Kyle Oct 15, 2009 @ 18:48

    Scot’s suggestion works absolutely perfectly.

  • Indie Feb 2, 2010 @ 17:49

    A slight variation on the original post which does it numerically and includes dot files.

    [ $(( $(ls -a1 $DIR | wc -l) >= 3 )) = 0 ] && echo Empty || echo Nope

    That’s a one and not an ‘l’ to the ls command. An empty directory only has the two entries – . & ..

  • nova May 6, 2010 @ 5:16

    Works with both BSD and GNU Linux find:
    find "/nas/data" -maxdepth 0 -empty -exec echo {} is empty. \;
    find "/dir2" type d -empty -exec command1 -arg1 {} \;

  • daniel Aug 9, 2010 @ 14:50

    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?

    • Crístian Viana Aug 9, 2010 @ 15:51

      enclose the directory name parameter in double quotes.

      • daniel Aug 10, 2010 @ 8:49

        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.


        DIR=”home/dan/not empty”
        if [ “$(ls -A $DIR)” ]; then
        echo “$DIR is not empty”
        echo “$DIR is empty”

        • SnakE Nov 13, 2010 @ 5:20


          if [ “$(ls -A $DIR)” ]; then


          if [ “$(ls -A “$DIR”)” ]; then

          That’s just another pair of quotes, no escapes. Should work.

  • pmcneil Oct 25, 2010 @ 6:14

    dude. give find some love ;-)

    find . -type d -empty -exec touch {}/.empty \;

  • anonymous Dec 9, 2010 @ 21:25

    find “/dir2” -type d -empty -exec command1 -arg1 {} \;

  • kevin Jan 8, 2011 @ 1:31

    if [ “$(ls -A $DIR)” ]; then
    How can I use this expression exclude one directory?

  • samoak May 4, 2011 @ 7:40

    what if the directory has files but each file is of 0 size?

    best way is to do as below:
    if [ -d “$dir_full_path” ] ; then
    if [ 4 -ge $(du -s “$dir_full_path” ] ; then
    echo “empty directory $dir_full_path”
    echo “non-empty directory $dir_full_path”

    This snippet assumes that a directory size, by its own name, is always 4096 bytes, approximated to 4.0K evaluated to int as 4

  • Jairo Nov 9, 2011 @ 4:29

    Hi all,
    someone please say me why this dont work.

    for dir in `ls -R “$src”`
    if [ -d “$dir” ]; then
    echo this is a dir: $dir


    • ReddyRace Dec 9, 2011 @ 21:58

      Jairo :

      Declare the variable ,before you use it.

  • stainless Jan 5, 2012 @ 15:09

    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:



    for i in $DIR/*
    if [ -e $i ] && [ $(echo $?) -eq “0 ” ]

    echo The Directory is NOT EMPTY


    echo The directory is EMPTY


  • Vijay Kanta Sep 12, 2012 @ 5:58

    Very good Vivek. Cool.

  • DejanLupo Sep 13, 2012 @ 10:46

    if [ $( stat -c %h . ) -gt 2 ] ; then echo not empty; fi
    Solution with “$(ls -A $DIR)” could exceed command buffer size.

  • plums Sep 18, 2012 @ 8:35

    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"
        echo "$DIR is Empty"


    if ls -A $DIR/* > /dev/null 2>&1; then
        echo "$DIR is Empty"
        echo "Take action $DIR is not Empty"
  • Gibarian Sep 26, 2012 @ 12:44

    If 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:

  • neuralys Nov 14, 2012 @ 12:46

    why not using simple :

    if [ ! -f /folder/* ]; then
    echo “folder not empty”
    echo “folder empty”

  • ThePowerTool Feb 15, 2013 @ 15:05

    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

    # 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


    while [ $i -le `wc -l ./testdir2.txt | gawk ‘{print $1}’` ]; do
    line=`head -$i ./testdir2.txt | tail -1`
    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”

    i=`expr $i + 1`


    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.

  • ThePowerTool Feb 15, 2013 @ 15:11

    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.

  • ThePowerTool Feb 15, 2013 @ 15:25

    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:

    # 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


    while [ $i -le `wc -l ./testdir2.txt | gawk ‘{print $1}’` ]; do
    line=`head -$i ./testdir2.txt | tail -1`
    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”

    i=`expr $i + 1`


    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.

  • ThePowerTool Feb 15, 2013 @ 15:43

    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)” ]

  • TheOne May 24, 2013 @ 21:07

    if [ ! “$(ls -A “$FOLDER”)” ]; then
    echo “$FOLDER is empty”

  • Jonathan D. Lettvin Jun 26, 2013 @ 18:57

    When searching for methods to automatically mount virtualbox shared folders,
    reliable and correct methods are hard to distinguish from those that fail.
    Failures include getting and setting permissions, as well as other problems.

    Methods that fail include:
    modifying /etc/fstab
    modifying /etc/rc.local

    I am fairly certain that rc.local can be used,
    but no methods I have tried worked.
    I welcome improvements on these guidelines.

    On virtualbox 4.2.14 running nautilus (bash terminal) on an ubuntu 13.04 guest,
    Below is a working method to mount Common (sharename)
    on /home/$USER/Desktop/Common (mountpoint) with full permissions.
    (Note the ‘\’ command continuation character in the find command.)

    First time only: create your mountpoint, modify your .bashrc file, and run it.
    Respond with password when requested.
    These are the four command-lines needed.

    mkdir $HOME/Desktop/Common
    sudo echo “$USER ALL=(ALL) NOPASSWD:ALL” >> /etc/sudoers
    find $HOME/Desktop/Common -maxdepth 0 -type d -empty -exec sudo \
    mount -t vboxsf -o \
    uid=`id -u $USER`,gid=`id -g $USER` Common $HOME/Desktop/Common \;
    source ~/.bashrc # Needed if you want to mount Common in this bash.

    All other times: simply launch a bash shell.

    The find command detects an empty mountpoint directory.
    If the Common directory is not empty, it does not run the mount command.

    I hope this is error-free and sufficiently general.
    Please let me know of corrections and improvements.

  • Janani Aug 4, 2013 @ 5:58

    How to make two directories “C_ Programming ” and “Shell Script” ?

  • Janani Aug 4, 2013 @ 6:01

    A)Create a text file “Pros_and_Cons_of_C.txt” in “C_programming” directory
    B)Create a text file “Pros_and_Cons_of_C.txt” in “Shell_Script” directory
    C)Write a suitable pros and cons for each text file in your own words using keyboards inputs.

  • Janani Aug 4, 2013 @ 6:06

    Write a shell script to create a directory “Shell2” Create 10 text files “a5_1.txt” “a5_10.txt” using loop inside the directory “Shell2.” Give access privilege for those text files , read only for others and group , read and write for owner..

    Please help me for above all forums that i sent. those are may be primary level questions , but i can’t understand for answer those questions. please help me for do my university assignment..

    Thank you

  • Philippe Petrinko Aug 6, 2013 @ 9:17


    That’s great for you, learning Linux computer science, and this means first: learn. Nobody can do it for you.
    Fortunately, somebody has built and offered to all a great resource to learn, which is also a cooperative work:


  • Philippe Petrinko Aug 6, 2013 @ 9:20


    I could have added, among other resources:

    Enjoy++ !

  • Erik Lundmark Oct 5, 2013 @ 14:49

    Not a better solution, but this also works:

    [[ `du $FOLDER` =~ ^4[^0-9] ]] && echo "is empty"
  • Erik Lundmark Oct 5, 2013 @ 14:55

    Please remove/disregard my previous comment, this is what I meant. Checks for just one folder (current one) and it’s size being 4096 bytes.

    [[ `du -ab $PWD` =~ ^4096[^0-9]+.$ ]] && echo "is empty"
  • Me Jun 6, 2014 @ 5:13


    rm -rf “%*”
    mkdir “%*”
    echo NOW it’s empty.
    exit 0

  • Chris Aug 26, 2014 @ 15:08

    Thanks for this post! I have a comment and a potential method.

    Method: Why wouldn’t this work?
    ls $DIR/*
    echo $? # a ‘1’ would mean the directory is empty

    Comment: As far as I can tell, this version, the find command version, and ls -A, will not detect a directory that contains subdirectories but is void of files. I am perplexed that the below does not work. Assume $DIR has a single subdirectory, foo, and neither have regular files:
    find $DIR -type f -exec echo $DIR is empty \;


  • Chris Aug 26, 2014 @ 15:25

    PS I did find for my ancillary problem (may contain subdirectories but no files) this solution:
    let “$m = `find $DIR -type f | wc -l`” ; test $m = 0 ; echo $?

    Also, a nit in my original suggestion: adjust the ls command so you don’t get unwanted output:
    ls $DIR/* > /dev/null
    echo $? # a ’1′ would mean the directory is empty

  • Ronald Jan 23, 2015 @ 12:54

    The example

    if [ “$(ls -A $DIR)” ]; then
    echo “Take action $DIR is not Empty”
    echo “$DIR is Empty”

    could be written a bit simpler without backquote substitution:

    if ls -A $DIR >/dev/null
    echo Take action ….
    echo $Dir is empty

  • Armin Gruner May 21, 2015 @ 16:15

    NO, this is not true. Your check

    if ls -A $DIR

    checks for the EXIT value of “ls”, which is 0 if directory $DIR exists (even if it is empty),

    [ “$(ls -A $DIR)” ] checks whether the OUTPUT of “ls” is non-empty, i.e. the directory is non-empty. See the man page test(1).

  • VVS Oct 29, 2015 @ 18:13
    if [ "`ls -A dir | head -1`" = "" ]; then echo dir is empty; fi
  • Michelle Mar 9, 2017 @ 22:07

    Thank you, VVS. Worked like a charm for a novice.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum