0
DIR=/u01/app/tomcat/apache-tomcat-9.0.43/work
if [ $(ls -A $DIR) ]
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

works fine and the output is

Folder is not empty.

however if I try it for /temp it fails. throwing error

DIR=/u01/app/tomcat/apache-tomcat-9.0.43/temp
if [ $(ls -A $DIR) ]
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

[: too many arguments Folder is empty

why is the /temp is not working.? The [: too many arguments Folder is empty error occurs only when the folder is not empty

1 Answers1

2

The comment about not parsing ls is right on the money. However, in this narrow instance the problem you have is to do with quoting.

This should work:

if [ "$(ls -A $DIR)" ]
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

But it's really a bad way to solve the problem, for multiple reasons.

Here's an alternative (copious others are bound to exist):

if find "${DIR}/" -maxdepth 1 -mindepth 1 | head -1 | grep -Eq "^.|^$"
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

The theory here being that the head -1 will cease the pipeline as soon as we discover a single entry, which should save some time in the event the directory has a lot of entries.

The grep -q "^.|^$" just confirms that something (or an empty line) was returned by the preceding commands.

Or...

Another way would be to look at the number of "links" the directory has. Any empty directory has exactly 2; one each for the special . and .. entries.

GNU stat

if stat --printf %h "${DIR}/" | grep -qvFx 2
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

MacOS native stat

if stat -f %l "${DIR}/" | grep -qvFx 2
then
        echo 'Folder is not empty'
else
        echo 'Folder is empty'
fi

Both of these assume that either the OS or filesystem will block directory hard linking and report two links when empty, if one or more of these are not the case, the find solution would be the better choice.

bxm
  • 4,855
  • Wouldn't that find pipeline think the directory was empty if the first found name starts with a newline? It's better to just expand * and count the number of matches. bash -O dotglob -O nullglob 'set -- "$1"/*; [[ $# -eq 0 ]]' bash some/path. – Kusalananda Feb 23 '22 at 23:24
  • No, because the first thing emitted is the directory name. However, if the directory you are looking at has a leading newline in its name, it would fail -- so thanks for the idea. Will fix. – bxm Feb 24 '22 at 22:18
  • I'm really not sure that expanding * is an efficient solution, how's that going to behave with 100 files, 1k files, 1m entries? I haven't tried it but would assume bad results ... and even if it works at higher counts, it just seems like a lot of "stuff" getting processed when we only need to know if a single entry exists. – bxm Feb 24 '22 at 22:34
  • Added a couple of stat based solutions. – bxm Feb 24 '22 at 22:57
  • Also note that there are filesystems that have zero hard links in an empty directory, e.g. btrfs. – Kusalananda Feb 25 '22 at 07:19