Reputation: 351
I'm trying to put a third check whether the directory contains only hidden files:
if [ ! "$(ls -A "$dir")" ]; then
echo "Specified directory is empty"
exit 1
elif [[ -z "$(find "$dir" -maxdepth 1 -type f)" ]]; then
echo "Specified directory contains only subdirectories and no files"
exit 1
elif [[ -z "$(find "$dir" -maxdepth 1 -type f | grep -v '"$dir"/.*')" ]]; then
echo "Specified directory contains only hidden files"
exit 1
fi
The third check is what is not working. I tried getting a list of all files that don't match '.*' and checking if it's empty with -z, but it always tests true. Do you have an idea?
Upvotes: 1
Views: 370
Reputation: 189397
Generally don't use ls
in scripts.
Assuming you have the default values for nullglob
etc,
files=(./*)
if [[ "${files[@]}" = './*' ]]; then
echo "Specified directory is empty" >&2
exit 1
fi
dirs=(./*/)
if [[ "${#dirs[@]}" = "${#files[@]}" ]]; then
echo "Specified directory contains only subdirectories and no files" >&2
exit 1
fi
hidden=(./.*)
if [[ "${#hidden[@]}" = "${#files[@]}" ]]; then
echo "Specified directory contains only hidden files" >&2
exit 1
fi
There is an obvious race condition here, in that another process could add a new hidden file after files
gets assigned, but before hidden
gets assigned, for example.
The use of arrays makes this Bash-only; this should be obvious, but many beginners are confused about the difference between sh
and bash
.
The immediate error in your attempt is that '"$dir"/.*'
is in single quotes, and so gets interpreted verbatim (and even if you fixed the quoting, .
in a regex matches any character, not a literal dot). But more broadly, it seems excessive to use find
when the shell itself can tell you what files you have.
Upvotes: 1