Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

bash - Checking from shell script if a directory contains files

From a shell script, how do I check if a directory contains files?

Something similar to this

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

but which works if the directory contains one or several files (the above one only works with exactly 0 or 1 files).

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Three best tricks


shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))

This trick is 100% bash and invokes (spawns) a sub-shell. The idea is from Bruno De Fraine and improved by teambob's comment.

files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
  echo "contains files"
else 
  echo "empty (or does not exist or is a file)"
fi

Note: no difference between an empty directory and a non-existing one (and even when the provided path is a file).

There is a similar alternative and more details (and more examples) on the 'official' FAQ for #bash IRC channel:

if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi

[ -n "$(ls -A your/dir)" ]

This trick is inspired from nixCraft's article posted in 2007. Add 2>/dev/null to suppress the output error "No such file or directory".
See also Andrew Taylor's answer (2008) and gr8can8dian's answer (2011).

if [ -n "$(ls -A your/dir 2>/dev/null)" ]
then
  echo "contains files (or is a file)"
else
  echo "empty (or does not exist)"
fi

or the one-line bashism version:

[[ $(ls -A your/dir) ]] && echo "contains files" || echo "empty"

Note: ls returns $?=2 when the directory does not exist. But no difference between a file and an empty directory.


[ -n "$(find your/dir -prune -empty)" ]

This last trick is inspired from gravstar's answer where -maxdepth 0 is replaced by -prune and improved by phils's comment.

if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

a variation using -type d:

if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
  echo "empty directory"
else
  echo "contains files (or does not exist or is not a directory)"
fi

Explanation:

  • find -prune is similar than find -maxdepth 0 using less characters
  • find -empty prints the empty directories and files
  • find -type d prints directories only

Note: You could also replace [ -n "$(find your/dir -prune -empty)" ] by just the shorten version below:

if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

This last code works most of the cases but be aware that malicious paths could express a command...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...