2011-10-31 03:47:31 +0000 2011-10-31 03:47:31 +0000
106
106

Bash脚本:测试空目录

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

我尝试了以下操作。

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

这给出了以下错误:

line 1: [: too many arguments

有什么解决办法吗?

答案 (18)

135
135
135
2011-10-31 03:53:28 +0000
if [-z "$(ls -A /path/to/dir)"]; then
   echo "Empty"
else
   echo "Not Empty"
fi

另外,如果能在之前检查一下目录是否存在,那就更好了。

24
24
24
2013-10-29 21:07:29 +0000

不需要计算任何东西或shell globs。你也可以将readfind结合使用。如果find的输出是空的,你会返回false

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

这应该是可移植的.

20
20
20
2011-10-31 10:53:57 +0000
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
14
14
14
2011-11-01 14:51:09 +0000
#!/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
4
4
4
2018-09-26 13:50:40 +0000

使用 FIND(1) (在 Linux 和 FreeBSD 下),你可以通过"-maxdepth 0 “来非递归地查看一个目录条目,并通过”-empty “来测试它是否为空。应用到这个问题上,可以得到

if test -n "$(find ./ -maxdepth 0 -empty)" ; then
    echo "No new file"
    exit 1
fi
4
4
4
2014-10-24 01:23:28 +0000

一个黑客的,但只有bash的,无PID的方法:

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

这利用了test内置的退出时,如果在-e后面给出多个参数,就会以2退出。首先,"$1"/* glob被bash扩展。这导致每个文件只有一个参数。所以

  • 如果没有文件,test -e "$1"*中的星号不会展开,所以Shell又落回尝试名为*的文件,返回1。

  • ……除非真的有一个文件的名字正是*,那么星号就会扩展为嗯,星号,结果和上面的调用一样,即test -e "dir/*",只是这次返回0(感谢@TrueY指出这一点。

  • 如果有一个文件,则运行test -e "dir/file",返回0.

  • 但如果文件比1多,则运行test -e "dir/file1" "dir/file2",bash将其报告为使用错误,即2.

case将整个逻辑绕了过去,所以只有第一种情况,退出状态为1,才报告为成功。

可能的问题,我还没有检查过:

  • 有更多的文件比允许的参数数量多–我想这可能与2个以上文件的情况类似。

  • 或者有一个空名的文件–我不确定这在任何正常的操作系统/FS上是否可能。

4
4
4
2011-10-31 10:06:28 +0000

这将在当前的工作目录(.)中执行工作:

[`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。我用 0x6& 替换了 0x6& (见 @Daniel 评论)

3
3
3
2011-10-31 10:17:15 +0000

使用以下方式。

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

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

3
3
3
2014-08-12 21:46:08 +0000

使用一个数组。

files=( * .* )
if (( ${#files[@]} == 2 )); then
    # contents of files array is (. ..)
    echo dir is empty
fi
2
2
2
2018-06-20 09:17:01 +0000

在一个if语句

if [[-d path/to/dir && -n "$(ls -A path/to/dir)"]]; then 
  echo "directory exists"
else
  echo "directory doesn't exist"
fi
```中测试目录是否存在且不为空怎么办?
1
1
1
2013-10-29 20:57:27 +0000

我认为最好的解决办法是:

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"

即使文件名中包含空格也能正常工作。

1
1
1
2020-02-16 18:53:46 +0000

问题是:

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

答案是:

if ls -1qA . | grep -q .
    then ! exit 1
    else : # Dir is empty
fi
```。
1
1
1
2018-05-25 17:06:53 +0000
if find "${DIR}" -prune ! -empty -exit 1; then
    echo Empty
else
    echo Not Empty
fi

EDIT: 我认为这个解决方案在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是没用的。

EDIT: gnu find 没有 -exit… 上面的解决方案适用于 NetBSD 的 find。对于GNU的find,这个应该是可行的。

if [-z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`"]; then
    echo Empty
else
    echo Not Empty
fi
0
0
0
2020-01-15 17:46:01 +0000

我做了这样的方法:

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
```。
0
0
0
2018-05-02 13:29:51 +0000

这对我来说是可行的,可以检查和处理../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
0
0
0
2012-02-24 10:06:37 +0000

这是所有伟大的东西 - 只是把它做成一个脚本,这样我就可以检查当前目录下面的空目录。下面的内容应该放到一个叫'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
-1
-1
-1
2018-01-10 17:12:56 +0000

对于当前目录以外的任何一个目录,你可以通过尝试rmdir来检查它是否为空,因为rmdir对于非空目录是保证失败的。如果rmdir成功了,而你其实是想让空目录存活下来,就再mkdir一次吧。

如果有其他进程可能会因为它们所知道的目录短暂地不存在而变得混乱,就不要使用这个黑客。

如果rmdir对你不起作用,而且你可能会测试可能包含大量文件的目录,任何依赖shell globbing的解决方案都可能变得缓慢和/或遇到命令行长度限制。在这种情况下,可能最好使用find。我能想到的最快的 find 解决方案是

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

这对 GNU 和 BSD 版本的 find 有效,但对 Solaris 版本的 find 则无效,因为它缺少所有这些 0x6& 操作符。爱你的工作,Oracle。

-3
-3
-3
2018-04-08 20:54:13 +0000

你可以尝试删除该目录,等待出错;如果该目录不是空的,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