我想测试目录是否不包含任何文件。如果是这样,我将跳过一些处理。

我尝试了以下操作:

if [ ./* == "./*" ]; then
    echo "No new file"
    exit 1
fi


出现以下错误:

line 1: [: too many arguments


是否有解决方案/替代方法?

评论

相关:stackoverflow.com/q/91368/52074

[[! -d“ $ dir”]] || [[-z`ls -A“ $ dir”`]] ||回显“ $ dir存在且不为空”

#1 楼

if [ -z "$(ls -A /path/to/dir)" ]; then
   echo "Empty"
else
   echo "Not Empty"
fi


此外,检查目录是否以前也很酷。

评论


不要使用&&和||同时!如果回显“不为空”失败,则将运行回显“空”!尝试echo“ test” && false ||回声“失败”!是的,我知道echo不会失败,但是如果您更改任何其他命令,您将会感到惊讶!

– uzsolt
2011年10月31日9:27



请提供至少一个上面的代码不起作用的示例。具体而言,此代码绝对正确。我希望问问者能够针对自己的目的对此进行调整

–安德烈·阿塔平(Andrey Atapin)
2011年10月31日9:56



我行中的/ empty在哪里?

–安德烈·阿塔平(Andrey Atapin)
2011年10月31日上午10:01

当/ path / to / dir包含空格并需要加引号时,我很难使此方法起作用。我使用了[$(ls -A“ $ path” | wc -l)-ne 0],其灵感来自@ ztank1013的答案。

–pix
2015年5月19日下午3:23

不好了!这段代码有一个非常重要的问题。应该是[[-n“ $(ls -A / path / to / dir)”];然后...请先更新答案,然后再有人将此代码粘贴到他们的服务器中的某个位置,然后黑客会弄清楚如何利用它。如果/ path / to / dir不为空,那么那里的文件名将作为参数传递给/ bin / test,这显然不是故意的。只需添加-n参数,即可解决问题。谢谢!

–爱德华·内德·哈维
16-12-5在21:20



#2 楼

无需计算任何东西或外壳球。您也可以将readfind结合使用。如果find的输出为空,则将返回false

if find /some/dir -mindepth 1 | read; then
   echo "dir not empty"
else
   echo "dir empty"
fi


这应该是可移植的。

评论


好的解决方案,但是我认为您的回声调用反映了错误的结果:在我的测试中(在Cygwin下)find。 -mindepth 1 |读取在非空目录中有141错误代码,在空目录中有0错误

–卢卡斯·西蒙(Lucas Cimon)
17年12月20日在9:17

@LucasCimon不在这里(macOS和GNU / Linux)。对于非空目录,read返回0,对于空目录,read返回1。

–slhck
17年12月20日在11:28

PSA不适用于set -o pipefail

– 32名上校
19 Sep 10 '19在2:07

使用-maxdepth 1也将有助于提高性能(在/ ...上进行测试,无需深入了解)。否则,为什么要使用|读取而不是测试-n $(查找)?并不是很糟糕,但是我认为这是我第一次看到这种阅读方式。

–user3459474
20年8月6日13:37



#3 楼

if [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
    echo "Empty directory"
else
    echo "Not empty or NOT a directory"
fi


评论


正确且快速。真好!

–l0b0
2012年2月24日上午11:00

它需要使用引号(2x)和测试-n才能正确且安全(使用名称中带有空格的目录进行测试,使用名称“ 0 = 1”的非空目录进行测试)。 ... [-n“ $(找到” $ DIR_TO_CHECK“ -maxdepth 0 -type d-空2> / dev / null)”]; ...

– Zrin
17 Mar 7 '17 at 23:51

@ivan_pozdeev事实并非如此,至少对于GNU查找而言。您可能正在考虑grep。 serverfault.com/questions/225798/…

–弗拉基米尔·潘捷列夫(Vladimir Panteleev)
18年6月19日在10:55



查找find“ $ DIR_TO_CHECK” -maxdepth 0 -type d -empty |可能更简单。 grep。,并依靠grep的退出状态。无论采用哪种方式,这都是解决此问题的正确方法。

–汤姆·安德森(Tom Anderson)
18年7月6日在13:56

我喜欢这样,不需要列出/读取/遍历目录中的所有文件。与基于“ ls”的解决方案不同,当目录中包含许多文件时,这应该可以更快地工作。

–oᴉɹǝɥɔ
20-10-3在18:24

#4 楼

#!/bin/bash
if [ -d /path/to/dir ]; then
    # the directory exists
    [ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
    # You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi


评论


一定是这样,不需要解析ls输出,只需查看它是否为空即可。对我而言,使用find感觉像是一种矫kill过正。

–akostadinov
2013年9月18日在12:34

#5 楼

这将在当前工作目录(。)中执行此工作:

[ `ls -1A . | wc -l` -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."


或同一命令分成三行只是为了提高可读性:

[ `ls -1A . | wc -l` -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."


如果需要在其他目标文件夹上运行,只需将ls -1A . | wc -l替换为ls -1A <target-directory> | wc -l

编辑:我将-1a替换为-1A(请参阅@Daniel评论)

评论


使用ls -A代替。有些文件系统没有。和..符号链接(根据文档)。

–丹尼尔·贝克♦
2011年10月31日上午10:12

谢谢@Daniel,我根据您的建议编辑了答案。我知道“ 1”也可能会被删除。

–ztank1013
2011年10月31日上午10:21

这没有什么坏处,但是如果不将其输出到终端,则暗示它。由于将其通过管道传输到另一个程序,因此是多余的。

–丹尼尔·贝克♦
2011年10月31日上午10:24

-1绝对是多余的。即使ls在管道传输时每行不会打印一项,也不会影响检查是否产生零行或更多行的想法。

– Victor Yarema
17-10-13在9:31

#6 楼

使用以下命令:

count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
   echo "No new file"
   exit 1
fi


这样,您将独立于ls的输出格式。 -mindepth跳过目录本身,-maxdepth防止递归防御子目录以加快处理速度。

评论


当然,您现在依赖于wc -l并找到输出格式(尽管这相当简单)。

–丹尼尔·贝克♦
2011年10月31日10:25



#7 楼

使用FIND(1)(在Linux和FreeBSD下),您可以通过“ -maxdepth 0”非递归地查看目录条目,并使用“ -empty”测试该目录是否为空。应用于以下给出的问题:

if test -n "$(find ./ -maxdepth 0 -empty)" ; then
    echo "No new file"
    exit 1
fi


评论


它可能不是100%可移植的,但是很优雅。

–克雷格·林格(Craig Ringer)
18年11月28日在2:59

这也可以在大型目录中尽早完成,可与pipefail一起使用:set -o pipefail; {找到“ $ DIR” -mindepth 1 ||真实; } |头-n1 |读取&&回显注意||回声空

– Macieksk
19-11-24在12:29



#8 楼

使用数组:

files=( * .* )
if (( ${#files[@]} == 2 )); then
    # contents of files array is (. ..)
    echo dir is empty
fi


评论


非常好的解决方案,但请注意,它需要shopt -s nullglob

– xebeche
17年1月16日,11:24



$ {#files [@]} == 2的假设并不代表根目录(您可能不会测试它是否为空,但有些代码可能不知道该限制)。

– ivan_pozdeev
18年1月21日在4:29

@ivan_pozdeev:你什么意思?当我执行cd / && files =(*。*)时,获取根目录中所有文件和目录的枚举,其中包括。和...因此$ {#files [@]} == 2测试有效。

–斯科特
20-2-3在4:08

#9 楼

一种骇人听闻但无bash且无PID的方式:

is_empty() {
    test -e "/"* 2>/dev/null
    case $? in
        1)   return 0 ;;
        *)   return 1 ;;
    esac
}


这利用了以下事实:如果在test之后给出多个参数,则内置-e会以2退出。 :首先,通过bash扩展""/* glob。这导致每个文件一个参数。因此,


如果没有文件,则test -e ""*中的星号不会扩展
,因此Shell将回退到尝试使用的名为*的文件,该文件返回
1。
...除非实际上只有一个文件名为*,否则
星号扩展为井号星号,其结果与上述
相同,即。 test -e "dir/*",这一次返回0。(感谢@TrueY
指出这一点。)
如果有一个文件,则运行test -e "dir/file",它返回0。
但是如果有更多文件大于1,则运行test -e "dir/file1" "dir/file2"
,bash将其报告为使用错误,即2。

case封装了整个逻辑,因此仅将第一种情况(退出状态为1)报告为成功。

我未检查过的可能问题:


文件多于允许的参数个数-我想这可能
类似于带有2个以上文件的情况。
或者实际上有一个文件名为空文件-我不确定在任何
健全的OS / FS上是否可以。


评论


较小的更正:如果dir /中没有文件,则调用test -e dir / *。如果dir中唯一的文件是“ *”,则test将返回0。如果有更多文件,则返回2。

– TrueY
18年9月7日在11:43

您是对的,@ TrueY,我已将其合并到答案中。谢谢!

–阿洛瓦·马哈德(Alois Mahdal)
18/09/11在14:45



#10 楼

如何测试目录中是否存在一个if语句中的目录是否为空

if [[ -d path/to/dir && -n "$(ls -A path/to/dir)" ]]; then 
  echo "directory exists"
else
  echo "directory doesn't exist"
fi


#11 楼

我认为最好的解决方案是:

files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty" 


感谢https://stackoverflow.com/a/91558/520567

对我的答案的匿名编辑可能对某人没有帮助:
稍​​作改动即可得到文件数量:

files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]}) 
echo "MYPATH contains $files files"


即使正确,它也可以正常工作如果文件名包含空格。

评论


使用数组而不是调用子shell会使情况变得更好。这个答案做到了。

– codeforester
20 Mar 6 '20 at 21:17

@codeforester,解决方案需要知道当前的shell选择。因此,需要代码来设置opts并在需要时进行还原(或找出opts并根据它们进行计数)。这会使代码the肿,并使代码的可读性降低。如果这部分代码位于性能关键的路径上,则可能值得(或不需要测试)。对于检查一个目录的正常用例,我认为此答案是安全,简短且自包含的。如果您不需要脚本之间的可移植性(可能使用不同的shell opt),那么另一个答案很好。

–akostadinov
20 Mar 8 '20 at 10:10

#12 楼

if find "${DIR}" -prune ! -empty -exit 1; then
    echo Empty
else
    echo Not Empty
fi


编辑:
在快速查看实现后,我认为该解决方案可以在gnu find上正常工作。
但这可能不适用于例如netbsd的find 。确实,那是使用stat(2)的st_size字段。该手册将其描述为:

st_size            The size of the file in bytes.  The meaning of the size
                   reported for a directory is file system dependent.
                   Some file systems (e.g. FFS) return the total size used
                   for the directory metadata, possibly including free
                   slots; others (notably ZFS) return the number of
                   entries in the directory.  Some may also return other
                   things or always report zero.


更好的解决方案,也更简单,是:

if find "${DIR}" -mindepth 1 -exit 1; then
    echo Empty
else
    echo Not Empty
fi


也,第一个解决方案中的-prune没用。

编辑:否-git find退出。上面的解决方案对NetBSD的查找很好。
对于GNU find,这应该可以工作:

if [ -z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`" ]; then
    echo Empty
else
    echo Not Empty
fi


评论


从GNU findutils 4.6.0(最新版本)查找没有-exit谓词。

–丹尼斯
18/09/11在15:13

#13 楼

此解决方案仅使用shell内置程序:

function is_empty() {
  typeset dir="${1:?Directory required as argument}"
  set -- ${dir}/*
  [ "" == "${dir}/*" ];
}

is_empty /tmp/emmpty && echo "empty" || echo "not empty"


#14 楼

这都是很棒的东西-只需将其放入脚本中,这样我就可以检查当前目录下的空目录。将以下内容放入名为“ findempty”的文件中,放置在路径中的某个位置,以便bash可以找到它,然后运行chmod 755。我想可以轻松地将其修改为您的特定需求。

#!/bin/bash
if [ "$#" == "0" ]; then 
find . -maxdepth 1 -type d -exec findempty "{}"  \;
exit
fi

COUNT=`ls -1A "$*" | wc -l`
if [ "$COUNT" == "0" ]; then 
echo "$* : $COUNT"
fi


#15 楼

对于除当前目录以外的任何目录,可以尝试尝试对其进行检查,以检查其是否为空,因为对于非空目录,rmdir一定会失败。如果rmdir成功执行,并且您实际上希望空目录能够通过测试,请再次进行修改。

如果有其他进程可能被他们知道的目录破坏,请不要使用此技巧。暂时停止存在。

如果rmdir不适用于您,并且您可能正在测试可能包含大量文件的目录,则任何依赖Shell Globing的解决方案都可能变慢和/或运行进入命令行长度限制。在这种情况下,使用mkdir可能更好。我能想到的最快的rmdir解决方案如下:

is_empty() {
    test -z $(find "" -mindepth 1 -printf X -quit)
}


这适用于find的GNU和BSD版本,但不适用于Solaris版本,因为Solaris缺少其中的每一个那些find运算符。爱您的工作,Oracle。

评论


这不是一个好主意。 OP只是想测试目录是否为空。

–roaima
18年5月2日在14:05

#16 楼

这项工作对我来说有用,可以检查和处理目录../IN中的文件,并考虑脚本位于../Script目录中:

FileTotalCount=0

    for file in ../IN/*; do
    FileTotalCount=`expr $FileTotalCount + 1`
done

if test "$file" = "../IN/*"
then

    echo "EXITING: NO files available for processing in ../IN directory. "
    exit

else

  echo "Starting Process: Found ""$FileTotalCount"" files in ../IN directory for processing."

# Rest of the Code


#17 楼

我采用了这种方法:

CHECKEMPTYFOLDER=$(test -z "$(ls -A /path/to/dir)"; echo $?)
if [ $CHECKEMPTYFOLDER -eq 0 ]
then
  echo "Empty"
elif [ $CHECKEMPTYFOLDER -eq 1 ]
then
  echo "Not Empty"
else
  echo "Error"
fi


#18 楼

问题是:

if [ ./* == "./*" ]; then
    echo "No new file"
    exit 1
fi


答案是:

if ls -1qA . | grep -q .
    then ! exit 1
    else : # Dir is empty
fi


#19 楼

[ $(ls -A "$path" 2> /dev/null | wc -l) -eq 0 ] && echo "Is empty or not exists." || echo "Not is empty."


评论


尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高​​答案的长期价值。

–唐老鸭
20年6月19日在17:44

#20 楼

我可能错过了与之等效的方法,它可以在Unix上使用
cd directory-concerned
ls * > /dev/null 2> /dev/null

返回代码($?的测试值)如果没有
将为2或找到0。请注意,这将忽略任何“。”。文件,如果其中任何一个存在而没有其他“正常”文件名,则可能会返回2。

#21 楼

使用find的更多解决方案

# Tests that a directory is empty.
# Will print error message if not empty to stderr and set return
# val to non-zero (i.e. evaluates as false)
#
function is_empty() {
    find  -mindepth 1   -exec false {} + -fprintf /dev/stderr "%H is not empty\n" -quit
    # prints error when dir is not empty to stderr
    # -fprintf /dev/stderr "%H is not empty\n"
    #
    # -exec false {} +
    # sets the return value (i.e. $?) to indicate error
    #
    # --quit
    # terminate after the first match

}

示例
#!/bin/bash
set -eE # stop execution upon error

function is_empty() {
    find  -mindepth 1   -exec false {} + -fprintf /dev/stderr "%H is not empty\n" -quit
}


trap 'echo FAILED' ERR
#trap "echo DONE" EXIT

# create a sandbox to play in
d=$(mktemp -d)
f=$d/blah # this will be a potention file

set -v # turn on debugging

# dir should be empty
is_empty $d

# create a file in the dir
touch $f
! is_empty $d

# this will cause the script to fail because the dir is not empty
is_empty $d

# this line will not execute
echo "we should not get here"

输出
[root@sysresccd ~/sandbox]# ./test

# dir should be empty
is_empty $d

# create a file in the dir
touch $f
! is_empty $d
/tmp/tmp.aORTHb3Trv is not empty

# this will cause the script to fail because the dir is not empty
is_empty $d
/tmp/tmp.aORTHb3Trv is not empty
echo FAILED
FAILED


#22 楼

您可以尝试删除目录并等待错误;
如果目录不为空,rmdir不会删除该目录。

_path="some/path"
if rmdir $_path >/dev/null 2>&1; then
   mkdir $_path        # create it again
   echo "Empty"
else
   echo "Not empty or doesn't exist"
fi


评论


-1这是适得其反的代码。如果我没有删除目录的权限,rmdir将失败;或者它是Btrfs子卷;或者它属于只读文件系统。如果rmdir不会失败并且mkdir运行:如果已经删除的目录属于另一个用户怎么办?它的(可能是非标准的)权限如何? ACL?扩展属性?全部丢了。

–卡米尔·马乔洛夫斯基(Kamil Maciorowski)
18年4月8日在21:37

好吧,我只是在学习bash,我认为这可能是一种更快的方法,而不是遍历所有目录,但是CPU功能强大,而且您是正确的而不是安全的。

– impxd
18年4月9日在5:21

-1。销毁某些东西以检查其状态绝不是一个好主意!

– codeforester
20 Mar 6 '20 at 21:18