Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to test if a directory doesn't contain any files. If so, I will skip some processing.

I tried the following:

if [ ./* == "./*" ]; then
    echo "No new file"
    exit 1
fi

That gives the following error:

line 1: [: too many arguments

Is there a solution/alternative?

share|improve this question

10 Answers 10

up vote 8 down vote accepted
if [ "$(ls -A /path/to/dir)" ]; then
   echo "Not Empty"
else
   echo "Empty"
fi

Also, it would be cool to check if the directory exists before.

share|improve this answer
2  
Don't use && and || simultaneously! If echo "Not Empty" fails, echo "Empty" will run! Try echo "test" && false || echo "fail"! Yes, I know echo will not fail but if you change any other command, you will be suprise! –  uzsolt Oct 31 '11 at 9:27
1  
Please, provide at least one example when the code above won't work. Concretely this code is absolutely correct. I hope that asker is able to adapt this for his own purposes –  Andrey Atapin Oct 31 '11 at 9:56
2  
[ "$(ls -A /)" ] && touch /non-empty || echo "Empty" - if you want "mark" the non-empty dirs with a created file named non-empty, will fails and prints "Empty". –  uzsolt Oct 31 '11 at 10:00
    
where's touch /empty in my line? –  Andrey Atapin Oct 31 '11 at 10:01
1  
Yes, you didn't wrote touch. But if you want more (other) than an echo "Not Empty", your script may be wrong! I've written this in my first comment, please read again (maybe you've read before my edit). –  uzsolt Oct 31 '11 at 10:04
if [ $(find $DIR_TO_CHECK -maxdepth 0 -type d -empty 2>/dev/null) ]; then
    echo "Empty directory"
else
    echo "Not empty or NOT a directory"
fi
share|improve this answer
    
Correct and fast. Nice! –  l0b0 Feb 24 '12 at 11:00
#!/bin/bash
if [ -d /path/to/dir ]; then
    # the directory exists
    [ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
    # You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi
share|improve this answer
1  
That must be it, no need for parsing ls output, just see if it is empty or not. Using find just feels like an overkill to me. –  akostadinov Sep 18 '13 at 12:34

This will do the job in the current working directory (.):

[ `ls -1A . | wc -l` -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."

or the same command split on three lines just to be more readable:

[ `ls -1A . | wc -l` -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."

Just replace ls -1A . | wc -l with ls -1A <target-directory> | wc -l if you need to run it on a different target folder.

Edit: I replaced -1a with -1A (see @Daniel comment)

share|improve this answer
1  
use ls -A instead. Some file systems don't have . and .. symbolic links according to the docs. –  Daniel Beck Oct 31 '11 at 10:12
    
Thanks @Daniel, I edited my answer after your suggestion. I know the "1" might be removed too. –  ztank1013 Oct 31 '11 at 10:21
1  
It doesn't hurt, but it's implied if output it not to a terminal. Since you pipe it to another program, it's redundant. –  Daniel Beck Oct 31 '11 at 10:24

Use the following:

count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
   echo "No new file"
   exit 1
fi

This way, you're independent of the output format of ls. -mindepth skips the directory itself, -maxdepth prevents recursively defending into subdirectories to speed things up.

share|improve this answer
    
Of course, you're now dependent on wc -l and find output format (which is reasonably plain though). –  Daniel Beck Oct 31 '11 at 10:25

This is all great stuff - just made it into a script so I can check for empty directories below the current one. The below should be put into a file called 'findempty', placed in the path somewhere so bash can find it and then chmod 755 to run. Can easily be amended to your specific needs I guess.

#!/bin/bash
if [ "$#" == "0" ]; then 
find . -maxdepth 1 -type d -exec findempty "{}"  \;
exit
fi

COUNT=`ls -1A "$*" | wc -l`
if [ "$COUNT" == "0" ]; then 
echo "$* : $COUNT"
fi
share|improve this answer

No need for counting anything or shell globs. You can also use read in combination with find. If find's output is empty, you'll return false:

if find /some/dir -mindepth 1 | read; then
   echo "dir not empty"
else
   echo "dir empty"
fi

This should be portable.

share|improve this answer

I think the best solution is:

files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty" 

thanks to http://stackoverflow.com/a/91558/520567

This is an anonymous edit of my answer that might or might not be helpful to somebody: A slight alteration gives the number of files:

files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]}) 
echo "MYPATH contains $files files"

This will work correctly even if filenames contains spaces.

share|improve this answer

Using an array:

files=( * .* )
if (( ${#files[@]} == 2 )); then
    # contents of files array is (. ..)
    echo dir is empty
fi
share|improve this answer

A hacky, but bash-only, PID-free way:

is_empty() {
    test -e "$1/"* 2>/dev/null
    case $? in;
        1)   return 0 ;;
        *)   return 1 ;;
    esac
}

This takes advantage of the fact that test builtin exits with 2 if given more than one argument after -e: First, "$1"/* glob is expanded by bash. This results in one argument per file. So

  • if there are no files, test -e "" is run, which obviously always fails, i.e. returns 1 for "no".

  • If there is one file, test -e "dir/file" is run, which returns 0.

  • But if there are more files than 1, bash reports it as usage error, i.e. 2.

case wraps the whole logic around so that only the first case, with 1 exit status is reported as success.

Possible problems I haven't checked:

  • There are more files than number of allowed arguments--I guess this could behave similar to case with 2+ files.

  • Or there is actually file with an empty name--I'm not sure it's possible on any sane OS/FS.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.