从shell脚本检查目录是否包含文件。

时间:2021-12-15 00:05:25

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

从shell脚本中,如何检查目录是否包含文件?

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).

但是,如果目录包含一个或多个文件(上面的文件只包含0或1个文件),那么该文件是有效的。

23 个解决方案

#1


56  

The solutions so far use ls. Here's an all bash solution:

到目前为止,解决方案使用ls。这里有一个all bash解决方案:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi

#2


99  

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.

这个技巧是100% bash并调用(生成)子shell。这个想法来自Bruno De Fraine,并由teambob的评论改进。

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:

关于#bash IRC通道的“官方”常见问题,有一个类似的替代和更多的细节(以及更多的例子):

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).

这一技巧来自于nixCraft 2007年发表的文章。添加2>/dev/null来抑制输出错误,“不存在这样的文件或目录”。参见安德鲁·泰勒的《答案》(2008)和gr8can8dian的答案(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:

或单行bashism版本:

[[ $(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.

注意:ls返回$ ?=2时,目录不存在。但是文件和空目录没有区别。


[ -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.

最后一个技巧来自于gravstar的答案——maxdepth 0被-prune替换,并由phils的评论改进。

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:

使用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 -prune与find -maxdepth 0相似,使用较少的字符。
  • find -empty prints the empty directories and files
  • 查找-空打印空目录和文件。
  • find -type d prints directories only
  • find -type d只打印目录。

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

注意:您还可以替换[-n "$(查找您/dir -prune -empty)"[参考译文]只要下面的短版本:

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...

这最后一段代码可以处理大多数情况,但是要知道恶意路径可以表示命令……

#3


47  

How about the following:

如何:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

This way there is no need for generating a complete listing of the contents of the directory. The read is both to discard the output and make the expression evaluate to true only when something is read (i.e. /some/dir/ is found empty by find).

这样就不需要生成目录内容的完整列表。读取是丢弃输出,并使表达式仅在读取某些内容时才会正确(例如,/某个/dir/被发现是空的)。

#4


18  

Try:

试一试:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi

#5


12  

# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}

#6


11  

Take care with directories with a lot of files! It could take a some time to evaluate the ls command.

注意目录中有很多文件!评估ls命令可能需要一段时间。

IMO the best solution is the one that uses

最好的解决方案是使用。

find /some/dir/ -maxdepth 0 -empty

#7


8  

DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi

#8


5  

Could you compare the output of this?

你能比较一下这个的输出吗?

 ls -A /some/dir | wc -l

#9


4  

# Checks whether a directory contains any nonhidden files.
#
# usage: if isempty "$HOME"; then echo "Welcome home"; fi
#
isempty() {
    for _ief in $1/*; do
        if [ -e "$_ief" ]; then
            return 1
        fi
    done
    return 0
}

Some implementation notes:

一些实现说明:

  • The for loop avoids a call to an external ls process. It still reads all the directory entries once. This can only be optimized away by writing a C program that uses readdir() explicitly.
  • for循环避免调用外部ls进程。它仍然读取所有的目录条目一次。这只能通过编写一个使用readdir()的C程序来优化。
  • The test -e inside the loop catches the case of an empty directory, in which case the variable _ief would be assigned the value "somedir/*". Only if that file exists will the function return "nonempty"
  • 在循环内的test -e捕获了空目录的情况,在这种情况下,变量_ief将被赋值为“somedir/*”。只有当该文件存在时,函数才返回“非空”
  • This function will work in all POSIX implementations. But be aware that the Solaris /bin/sh doesn't fall into that category. Its test implementation doesn't support the -e flag.
  • 该函数将在所有POSIX实现中工作。但是要注意Solaris /bin/sh不属于这一类。它的测试实现不支持-e标志。

#10


2  

This may be a really late response but here is a solution that works. This line only recognizes th existance of files! It will not give you a false positive if directories exist.

这可能是一个很晚的反应,但这是一个可行的解决方案。这一行只识别文件的存在!如果目录存在,它不会给你一个假阳性。

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi

#11


2  

This tells me if the directory is empty or if it's not, the number of files it contains.

这告诉我,如果目录是空的,或者它不是,它包含的文件的数量。

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi

#12


1  

dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

Assume you don't have a file named * into /any/dir/you/check, it should work on bash dash posh busybox sh and zsh but (for zsh) require unsetopt nomatch.

假设您没有一个名为* into /any/dir/您/检查的文件,它应该在bash dash时髦busybox sh和zsh上工作,但是(对于zsh)需要unsetopt nomatch。

Performances should be comparable to any ls which use *(glob), I guess will be slow on directories with many nodes (my /usr/bin with 3000+ files went not that slow), will use at least memory enough to allocate all dirs/filenames (and more) as they are all passed (resolved) to the function as arguments, some shell probably have limits on number of arguments and/or length of arguments.

性能应该与任何ls使用*(一滴),我想将是缓慢的目录与许多节点上(我和3000 +的工作文件就不慢),将使用至少足够内存分配所有dirs /文件名(以及更多)他们都是通过(解决)函数作为参数,一些shell可能限制数量的参数和/或参数的长度。

A portable fast O(1) zero resources way to check if a directory is empty would be nice to have.

一个可移动的快速O(1)零资源的方法来检查一个目录是否为空,这将是很好的。

update

更新

The version above doesn't account for hidden files/dirs, in case some more test is required, like the is_empty from Rich’s sh (POSIX shell) tricks:

上面的版本不考虑隐藏的文件/dirs,以防需要进行更多的测试,比如Rich的sh (POSIX shell)技巧中的is_empty:

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

But, instead, I'm thinking about something like this:

但是,我想的是:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

Some concern about trailing slashes differences from the argument and the find output when the dir is empty, and trailing newlines (but this should be easy to handle), sadly on my busybox sh show what is probably a bug on the find -> dd pipe with the output truncated randomically (if I used cat the output is always the same, seems to be dd with the argument count).

一些担忧斜杠差异论证和找到输出当dir是空的,和拖尾换行(但这应该易于处理),遗憾的是在我的busybox sh显示什么可能是一个错误的发现- > dd管输出截断randomically(如果我用猫的输出总是相同的,似乎是dd的参数数量)。

#13


1  

Small variation of Bruno's answer:

布鲁诺回答的小变化:

files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ] 
then
    echo "Contains files"
else
    echo "Empty"
fi

It works for me

它适合我

#14


0  

if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;

#15


0  

I am surprised the wooledge guide on empty directories hasn't been mentioned. This guide, and all of wooledge really, is a must read for shell type questions.

我很惊讶空目录的指南没有被提及。这个指南,以及所有的wooledge,都是shell类型问题的必读。

Of note from that page:

从那一页的说明:

Never try to parse ls output. Even ls -A solutions can break (e.g. on HP-UX, if you are root, ls -A does the exact opposite of what it does if you're not root -- and no, I can't make up something that incredibly stupid).

永远不要尝试解析ls输出。即使是ls -- -一个解决方案也可以中断(例如,在HP-UX上,如果你是root, ls -A与它所做的完全相反,如果你不是root用户——而且,我不能编出一个非常愚蠢的东西)。

In fact, one may wish to avoid the direct question altogether. Usually people want to know whether a directory is empty because they want to do something involving the files therein, etc. Look to the larger question. For example, one of these find-based examples may be an appropriate solution:

事实上,人们可能希望避免直接的问题。通常人们想知道一个目录是否为空,因为他们想做一些涉及到其中的文件的事情,等等。例如,其中一个基于find的示例可能是一个合适的解决方案:

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

Most commonly, all that's really needed is something like this:

最常见的是,需要的是这样的:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

In other words, the person asking the question may have thought an explicit empty-directory test was needed to avoid an error message like mympgviewer: ./*.mpg: No such file or directory when in fact no such test is required.

换句话说,问这个问题的人可能认为需要一个显式的空目录测试,以避免像mympgviewer: ./*这样的错误消息。mpg:没有这样的文件或目录,实际上不需要这样的测试。

#16


0  

So far I haven't seen an answer that uses grep which I think would give a simpler answer (with not too many weird symbols!). Here is how I would check if any files exist in the directory using bourne shell:

到目前为止,我还没有看到一个使用grep的答案,我认为这个答案会给出一个简单的答案(没有太多奇怪的符号!)下面是我如何检查使用bourne shell的目录中是否存在任何文件:

this returns the number of files in a directory:

这将返回目录中文件的数量:

ls -l <directory> | egrep -c "^-"

you can fill in the directory path in where directory is written. The first half of the pipe ensures that the first character of output is "-" for each file. egrep then counts the number of line that start with that symbol using regular expressions. now all you have to do is store the number you obtain and compare it using backquotes like:

您可以在目录中填写目录路径。管道的前半部分确保输出的第一个字符是“-”用于每个文件。然后使用正则表达式计算从该符号开始的行数。现在你所要做的就是储存你获得的数字,并将其与后面的引用进行比较:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x is a variable of your choice.

x是你选择的变量。

#17


0  

Mixing prune things and last answers, I got to

把所有的东西和最后的答案混在一起,我必须。

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

that works for paths with spaces too

这也适用于有空间的路径。

#18


0  

Simple answer with bash:

与bash简单的答案:

if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;

#19


0  

I would go for find:

我会去寻找:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

This checks the output of looking for just files in the directory, without going through the subdirectories. Then it checks the output using the -z option taken from man test:

这将检查在目录中查找文件的输出,而不需要通过子目录。然后使用man测试中的-z选项检查输出:

   -z STRING
          the length of STRING is zero

See some outcomes:

看到一些结果:

$ mkdir aaa
$ dir="aaa"

Empty dir:

空dir:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Just dirs in it:

只是dirs:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

A file in the directory:

目录中的文件:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

A file in a subdirectory:

子目录中的文件:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

#20


0  

Try with command find. Specify the directory hardcoded or as argument. Then initiate find to search all files inside the directory. Check if return of find is null. Echo the data of find

尝试与命令。指定目录硬编码或作为参数。然后开始查找目录内的所有文件。检查查找的返回是否为空。重复查找的数据。

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi

#21


-1  

I dislike the ls - A solutions posted. Most likely you wish to test if the directory is empty because you don't wish to delete it. The following does that. If however you just wish to log an empty file, surely deleting and recreating it is quicker then listing possibly infinite files?

我不喜欢ls -一个发布的解决方案。很可能您希望测试目录是否为空,因为您不希望删除它。以下这。如果您只是希望记录一个空文件,那么删除和重新创建它会更快,然后列出可能的无限文件吗?

This should work...

这应该工作……

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi

#22


-1  

to test a specific target directory

测试一个特定的目标目录。

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;

#23


-3  

Works well for me this (when dir exist):

这对我来说很有效(当dir存在时):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

With full check:

全面检查:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi

#1


56  

The solutions so far use ls. Here's an all bash solution:

到目前为止,解决方案使用ls。这里有一个all bash解决方案:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi

#2


99  

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.

这个技巧是100% bash并调用(生成)子shell。这个想法来自Bruno De Fraine,并由teambob的评论改进。

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:

关于#bash IRC通道的“官方”常见问题,有一个类似的替代和更多的细节(以及更多的例子):

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).

这一技巧来自于nixCraft 2007年发表的文章。添加2>/dev/null来抑制输出错误,“不存在这样的文件或目录”。参见安德鲁·泰勒的《答案》(2008)和gr8can8dian的答案(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:

或单行bashism版本:

[[ $(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.

注意:ls返回$ ?=2时,目录不存在。但是文件和空目录没有区别。


[ -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.

最后一个技巧来自于gravstar的答案——maxdepth 0被-prune替换,并由phils的评论改进。

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:

使用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 -prune与find -maxdepth 0相似,使用较少的字符。
  • find -empty prints the empty directories and files
  • 查找-空打印空目录和文件。
  • find -type d prints directories only
  • find -type d只打印目录。

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

注意:您还可以替换[-n "$(查找您/dir -prune -empty)"[参考译文]只要下面的短版本:

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...

这最后一段代码可以处理大多数情况,但是要知道恶意路径可以表示命令……

#3


47  

How about the following:

如何:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

This way there is no need for generating a complete listing of the contents of the directory. The read is both to discard the output and make the expression evaluate to true only when something is read (i.e. /some/dir/ is found empty by find).

这样就不需要生成目录内容的完整列表。读取是丢弃输出,并使表达式仅在读取某些内容时才会正确(例如,/某个/dir/被发现是空的)。

#4


18  

Try:

试一试:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi

#5


12  

# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}

#6


11  

Take care with directories with a lot of files! It could take a some time to evaluate the ls command.

注意目录中有很多文件!评估ls命令可能需要一段时间。

IMO the best solution is the one that uses

最好的解决方案是使用。

find /some/dir/ -maxdepth 0 -empty

#7


8  

DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi

#8


5  

Could you compare the output of this?

你能比较一下这个的输出吗?

 ls -A /some/dir | wc -l

#9


4  

# Checks whether a directory contains any nonhidden files.
#
# usage: if isempty "$HOME"; then echo "Welcome home"; fi
#
isempty() {
    for _ief in $1/*; do
        if [ -e "$_ief" ]; then
            return 1
        fi
    done
    return 0
}

Some implementation notes:

一些实现说明:

  • The for loop avoids a call to an external ls process. It still reads all the directory entries once. This can only be optimized away by writing a C program that uses readdir() explicitly.
  • for循环避免调用外部ls进程。它仍然读取所有的目录条目一次。这只能通过编写一个使用readdir()的C程序来优化。
  • The test -e inside the loop catches the case of an empty directory, in which case the variable _ief would be assigned the value "somedir/*". Only if that file exists will the function return "nonempty"
  • 在循环内的test -e捕获了空目录的情况,在这种情况下,变量_ief将被赋值为“somedir/*”。只有当该文件存在时,函数才返回“非空”
  • This function will work in all POSIX implementations. But be aware that the Solaris /bin/sh doesn't fall into that category. Its test implementation doesn't support the -e flag.
  • 该函数将在所有POSIX实现中工作。但是要注意Solaris /bin/sh不属于这一类。它的测试实现不支持-e标志。

#10


2  

This may be a really late response but here is a solution that works. This line only recognizes th existance of files! It will not give you a false positive if directories exist.

这可能是一个很晚的反应,但这是一个可行的解决方案。这一行只识别文件的存在!如果目录存在,它不会给你一个假阳性。

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi

#11


2  

This tells me if the directory is empty or if it's not, the number of files it contains.

这告诉我,如果目录是空的,或者它不是,它包含的文件的数量。

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi

#12


1  

dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

Assume you don't have a file named * into /any/dir/you/check, it should work on bash dash posh busybox sh and zsh but (for zsh) require unsetopt nomatch.

假设您没有一个名为* into /any/dir/您/检查的文件,它应该在bash dash时髦busybox sh和zsh上工作,但是(对于zsh)需要unsetopt nomatch。

Performances should be comparable to any ls which use *(glob), I guess will be slow on directories with many nodes (my /usr/bin with 3000+ files went not that slow), will use at least memory enough to allocate all dirs/filenames (and more) as they are all passed (resolved) to the function as arguments, some shell probably have limits on number of arguments and/or length of arguments.

性能应该与任何ls使用*(一滴),我想将是缓慢的目录与许多节点上(我和3000 +的工作文件就不慢),将使用至少足够内存分配所有dirs /文件名(以及更多)他们都是通过(解决)函数作为参数,一些shell可能限制数量的参数和/或参数的长度。

A portable fast O(1) zero resources way to check if a directory is empty would be nice to have.

一个可移动的快速O(1)零资源的方法来检查一个目录是否为空,这将是很好的。

update

更新

The version above doesn't account for hidden files/dirs, in case some more test is required, like the is_empty from Rich’s sh (POSIX shell) tricks:

上面的版本不考虑隐藏的文件/dirs,以防需要进行更多的测试,比如Rich的sh (POSIX shell)技巧中的is_empty:

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

But, instead, I'm thinking about something like this:

但是,我想的是:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

Some concern about trailing slashes differences from the argument and the find output when the dir is empty, and trailing newlines (but this should be easy to handle), sadly on my busybox sh show what is probably a bug on the find -> dd pipe with the output truncated randomically (if I used cat the output is always the same, seems to be dd with the argument count).

一些担忧斜杠差异论证和找到输出当dir是空的,和拖尾换行(但这应该易于处理),遗憾的是在我的busybox sh显示什么可能是一个错误的发现- > dd管输出截断randomically(如果我用猫的输出总是相同的,似乎是dd的参数数量)。

#13


1  

Small variation of Bruno's answer:

布鲁诺回答的小变化:

files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ] 
then
    echo "Contains files"
else
    echo "Empty"
fi

It works for me

它适合我

#14


0  

if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;

#15


0  

I am surprised the wooledge guide on empty directories hasn't been mentioned. This guide, and all of wooledge really, is a must read for shell type questions.

我很惊讶空目录的指南没有被提及。这个指南,以及所有的wooledge,都是shell类型问题的必读。

Of note from that page:

从那一页的说明:

Never try to parse ls output. Even ls -A solutions can break (e.g. on HP-UX, if you are root, ls -A does the exact opposite of what it does if you're not root -- and no, I can't make up something that incredibly stupid).

永远不要尝试解析ls输出。即使是ls -- -一个解决方案也可以中断(例如,在HP-UX上,如果你是root, ls -A与它所做的完全相反,如果你不是root用户——而且,我不能编出一个非常愚蠢的东西)。

In fact, one may wish to avoid the direct question altogether. Usually people want to know whether a directory is empty because they want to do something involving the files therein, etc. Look to the larger question. For example, one of these find-based examples may be an appropriate solution:

事实上,人们可能希望避免直接的问题。通常人们想知道一个目录是否为空,因为他们想做一些涉及到其中的文件的事情,等等。例如,其中一个基于find的示例可能是一个合适的解决方案:

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

Most commonly, all that's really needed is something like this:

最常见的是,需要的是这样的:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

In other words, the person asking the question may have thought an explicit empty-directory test was needed to avoid an error message like mympgviewer: ./*.mpg: No such file or directory when in fact no such test is required.

换句话说,问这个问题的人可能认为需要一个显式的空目录测试,以避免像mympgviewer: ./*这样的错误消息。mpg:没有这样的文件或目录,实际上不需要这样的测试。

#16


0  

So far I haven't seen an answer that uses grep which I think would give a simpler answer (with not too many weird symbols!). Here is how I would check if any files exist in the directory using bourne shell:

到目前为止,我还没有看到一个使用grep的答案,我认为这个答案会给出一个简单的答案(没有太多奇怪的符号!)下面是我如何检查使用bourne shell的目录中是否存在任何文件:

this returns the number of files in a directory:

这将返回目录中文件的数量:

ls -l <directory> | egrep -c "^-"

you can fill in the directory path in where directory is written. The first half of the pipe ensures that the first character of output is "-" for each file. egrep then counts the number of line that start with that symbol using regular expressions. now all you have to do is store the number you obtain and compare it using backquotes like:

您可以在目录中填写目录路径。管道的前半部分确保输出的第一个字符是“-”用于每个文件。然后使用正则表达式计算从该符号开始的行数。现在你所要做的就是储存你获得的数字,并将其与后面的引用进行比较:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x is a variable of your choice.

x是你选择的变量。

#17


0  

Mixing prune things and last answers, I got to

把所有的东西和最后的答案混在一起,我必须。

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

that works for paths with spaces too

这也适用于有空间的路径。

#18


0  

Simple answer with bash:

与bash简单的答案:

if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;

#19


0  

I would go for find:

我会去寻找:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

This checks the output of looking for just files in the directory, without going through the subdirectories. Then it checks the output using the -z option taken from man test:

这将检查在目录中查找文件的输出,而不需要通过子目录。然后使用man测试中的-z选项检查输出:

   -z STRING
          the length of STRING is zero

See some outcomes:

看到一些结果:

$ mkdir aaa
$ dir="aaa"

Empty dir:

空dir:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Just dirs in it:

只是dirs:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

A file in the directory:

目录中的文件:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

A file in a subdirectory:

子目录中的文件:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

#20


0  

Try with command find. Specify the directory hardcoded or as argument. Then initiate find to search all files inside the directory. Check if return of find is null. Echo the data of find

尝试与命令。指定目录硬编码或作为参数。然后开始查找目录内的所有文件。检查查找的返回是否为空。重复查找的数据。

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi

#21


-1  

I dislike the ls - A solutions posted. Most likely you wish to test if the directory is empty because you don't wish to delete it. The following does that. If however you just wish to log an empty file, surely deleting and recreating it is quicker then listing possibly infinite files?

我不喜欢ls -一个发布的解决方案。很可能您希望测试目录是否为空,因为您不希望删除它。以下这。如果您只是希望记录一个空文件,那么删除和重新创建它会更快,然后列出可能的无限文件吗?

This should work...

这应该工作……

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi

#22


-1  

to test a specific target directory

测试一个特定的目标目录。

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;

#23


-3  

Works well for me this (when dir exist):

这对我来说很有效(当dir存在时):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

With full check:

全面检查:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi