You are not logged in.
Sometimes I use ls -A and then check for an empty string with if -z.
Sometimes I do the same with find.
But every time I do one or the other I feel there should be a better way to handle this.
For anyone coming from the Windows world linux has some things a bit annoying at first glance -I am not saying there's something wrong with them, but, I suppose some things for directory handling are ... weird.
Like when you want to get everything in x directory (without descending the tree) and NOT the directory itself and you immediately start toying with al those annoying find switches (and then you use prune and want to delete the directory contents but prune and delete don't like each other etc etc); eg:
find /x -prune;
find /x -maxdepth 1 -name '*';
find /x -maxdepth 1 -name '.*';This simple thing of clearing the contents of any given directory within a shell script did bite me more times that I can remember since for whatever reasons I never manage to find a standard way of doing it -furthermore, take a directory like any user home directory that have file names prefixed with dots and you can't use * since it ignores them.
By the way, I think (and this is my PERSONAL opinion) that file names prefixed with dots was a very bad design decision from the start.
Last edited by dawnofman (2022-04-17 17:33:06)
Offline
Like when you want to get everything in x directory (without descending the tree) and NOT the directory itself
ls -A $directoryBut I'm not sure how this relates to your title on checking if a directory is empty. For that you might be interested in find's '-empty' flag which works as one would expect on directories. Or perhaps something like the following:
if [ -z "$(find $directory -mindepth 1)" ]; then
# directory is empty
fiLast edited by Trilby (2022-04-03 23:00:04)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Offline
Thanks for your reply jason.
The "problem" with the examples provided by your link, is that all of them rely on enumerating the directory content, then placing all of them in a BASH array to then check with a test whether the array is empty or not.
It is not efficient at all (nowadays there are directories that have zillion entries) and remembering how to do it every time is not straightforward either.
I guess/suppose there have to be a simple command that checks whether the inode on the file-system has childs or not -as simple as that, without the need to retrieve everything under said directory.
Offline
For that you might be interested in find's '-empty' flag which works as one would expect on directories.
I won't lie to you, I read the find man page many many times and totally missed the -empty flag. Maybe due to this in the find man page:
"Tests: Tests return a true or false value, usually on the basis of some property of a file we are considering. The -empty test for example is true only when the current file is empty."
I never associated the empty flag with a directory. Or maybe I forgot. The point is that I don't remembered it at all.
find is a powerful command but to me it always felt counter-intuitive in many scenarios, the most obvious is the one related to this post: if I issue find /whatever I (as a mere mortal) expects find to FIND me everything under the directory I give and not the directory itself, I "already" found the directory I want to further inspect.
Offline
And for that I noted the -mindepth flag
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
And for that I noted the -mindepth flag
if on an empty directory I do:
find /whatever/whateverelse -mindepth 0I get:
/whatever/whateverelseif on an non-empty directory I do:
find /whatever/whateverelse -mindepth 0I get:
/whatever/whateverelse
/whatever/whateverelse/file1
/whatever/whateverelse/file2
/whatever/whateverelse/anotherdirectorySo I suppose I can do:
strPATH='/whatever/whateverelse';
if test $(find ${strPATH} -mindepth 0) = "${strPATH}"; then
# the directory is empty
fi;Offline
1 # Bourne
2 find "$somedir" -type f -exec echo Found unexpected file {} \;
3 find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \; # GNU/BSD
4 find "$somedir" -type d -empty -exec cp /my/configfile {} \; # GNU/BSD
Number 3 would be perfect ... but it does not work on arch, it is BSD-only.
Offline
And for that I noted the -mindepth flag
find having something like -maxresults would be great:
find /whatever -maxresults 2/whatever
/whatever/1you get other than 1 bingo; empty directory; besides it would be very useful for a lot of other cases like inspecting huge directories etc
Offline
Ah, yeah, -mindepth 0 is a noop ... that's why I gave the example with -mindepth 1.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Ah, yeah, -mindepth 0 is a noop ... that's why I gave the example with -mindepth 1.
After reading some man pages and giving some thought to it I ended thinking this issue should have to be addressed by test in coreutils; it is the natural place for it.
test currently have:
-e FILE ... FILE exists
-d FILE ... FILE exists and is a directory
-s FILE ... FILE exists and has a size greater than zero
... maybe:
-? FILE ... FILE exists and is empty
-? FILE ... FILE exists and is a directory and is empty
something like that; those two switches could simplify scripts a lot, my opinion, of course
Offline
Ah ... what? If you are proposing new test flags, you are in the wrong place. If you are looking for help to get you script working, you've been given several options.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Ah ... what? If you are proposing new test flags, you are in the wrong place. If you are looking for help to get you script working, you've been given several options.
I was just thinking aloud while on the subject. I know, you're right, the place is coreutils on gnu.org
You're right on your second statement too: I've been given advice here and I am very grateful, no doubt about it ![]()
Offline
Ah, yeah, -mindepth 0 is a noop ... that's why I gave the example with -mindepth 1.
Given:
./whatever/
./whatever/file1
./whatever/file2
./whateverelse/
./whateverelse/file3
./whateverelse/file4I think I finally solved this issue with:
find ./whatever/ -mindepth 1 -maxdepth 1 -print0 -quit./whatever/file1mindepth 1 alognside maxdepth 1 keeps me within the directory without descending and without including the directory I am checking to begin with
print0 needs no description
quit stops the find process immediately after the first match; thus avoiding enumerating everything within the directory --a plus for performance on huge directories
... so:
strPATH='./whatever';
if test -z $(find "${strPATH}" -mindepth 1 -maxdepth 1 -print0 -quit); then
### directory is empty
fi;Offline
How is maxdepth relevant if your question is whether the toplevel directory is empty? If there is anything there to be pruned by maxdepth, then the toplevel directory is not empty. And the code you put in your last post may run the "### directory is empty" block even if the directory is not empty.
Is what you really wanted to know whether "./whatever/" had nothing but directories in it? If so, do you care what's in those directories for this test? If your actual question is whether there are any files in a directory you can just ask find that:
find ./whatever -maxdepth 1 -type f(edit: fixed typo of a missing "1" in the command)
Last edited by Trilby (2022-04-05 13:21:16)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline