Linux 如何检查文件夹是否为空或文件夹文件是否使用shell脚本?
我有个问题 我尝试了一些函数,比如 DIR=/path/tmp/ 如果[-d“$DIR”];然后 及 如果[-f“$DIR”];然后 但仅检查/path/tmp此路径Linux 如何检查文件夹是否为空或文件夹文件是否使用shell脚本?,linux,shell,Linux,Shell,我有个问题 我尝试了一些函数,比如 DIR=/path/tmp/ 如果[-d“$DIR”];然后 及 如果[-f“$DIR”];然后 但仅检查/path/tmp此路径 我该怎么办?为什么不使用ls-v?因此,如果没有文件,例如 if $(ls -v $DIR) rmdir“$DIR” 如果$?为1,则目录不是空的。如果为0,则为空,并将其删除 如果您不想删除它,可以重新创建它:mkdir“$DIR”您可以使用ls-A执行此操作: if [ "$(ls -A "$DIR" 2> /dev/
我该怎么办?为什么不使用
ls-v
?因此,如果没有文件,例如
if $(ls -v $DIR)
rmdir“$DIR”
如果$?
为1,则目录不是空的。如果为0,则为空,并将其删除
如果您不想删除它,可以重新创建它:
mkdir“$DIR”
您可以使用ls-A
执行此操作:
if [ "$(ls -A "$DIR" 2> /dev/null)" == "" ]; then
# The directory is empty
fi
-A
显示除始终存在的
和之外的所有隐藏文件和目录。
因此在空目录中为空,在包含任何文件或子目录的目录中为非空
2>/dev/null
会丢弃任何可能打印的错误消息ls
(请注意,检查不存在的目录会产生误报,但您说您已经检查了它是否存在)。检查没有读取权限的目录也会产生误判。从#4--如何检查目录是否为空?
这个小脚本用路径扩展中找到的每个文件填充数组文件*
。然后检查数组的大小,如果为0,则打印“目录为空”。由于使用了dotglob
,这将适用于隐藏文件
注
要求解析ls
的答案通常是一个坏主意和糟糕的形式。要了解原因,请阅读这会告诉我目录是否为空,它包含的文件数
directory="/path/tmp"
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
要仅使用shell内置程序执行此操作(应适用于我使用过的所有shell):
我们不检查/tmp/testdir/*,因为它将扩展到/tmp/testdir//tmp/testdir/。。对于空文件夹
另一个仅内置的变体:
for i in /tmp/testdir/* /tmp/testdir/.?*; do
test -e $i || break
[...]
break
done
find
具有谓词-empty
,该谓词测试目录或文件是否为空,因此它将仅在目录为空时列出目录-z
测试find的输出是否为空。如果是,则目录包含条目,如果不是,则为空
换言之:
[ -n "$(find "$DIR" -maxdepth 0 -empty)" ] && echo "$DIR is empty!"
另一个很好的例子:
if ! ls -AU "$DIR" | read _; then
echo "$DIR is empty!"
fi
为什么-v
(“文本中数字的自然排序”)?速度?此外,这不会检查隐藏文件。如果目录不为空,则会产生错误。如果执行操作,如果ls-v$DIR
则没有错误,但总是正确的。您必须执行if[“$(ls-v“$DIR”)”]
或if[[$(ls-v“$DIR”)]]
。使用
来反转逻辑,如果需要的话。他没有说他想删除目录。删除它只是为了发现它是否为空是一个非常糟糕的主意。因为你正在删除目录,而他没有说他想这么做。可能还有另一个进程要写入目录。也许他没有权利移除它。关键是,这是一个破坏性的操作,不需要。对于非ls
解决方案,+1,但请注意,我的答案并没有解析ls
的输出。它只是检查是否有任何错误。:-)如果我想在php systen()中使用它;它可以使用?另一个问题文件可以使用路径?如果目录包含大量条目(长名称),这将是不利的,因为它将所有条目加载到内存中只是为了检查是否有条目。如果目录包含大量条目(长名称),这可能是不利的。另外,“$DIR”需要引号。要解释这一点-。。。[“$(ls-A“$DIR”2>/dev/null | head-n 1)”==”]…
@Zrin:在没有任何转义或任何内容的情况下将引号放在引号中感觉非常奇怪,但我对它进行了测试,您完全正确(至少,我对带有空格的目录名的测试与我的原始测试失败,并处理了您的更改)。谢谢但是,| head-n1
实际上有什么帮助吗ls
仍然会生成完整的列表,不是吗?@t-j-crowder| head-n1
将从ls
中获取第一行,输出它,然后剪切输入-即它说“够了!”还有一个很好的解决方案是使用读取而不是头部-尝试|读取,然后检查退出代码。@Zrin:我知道头部的功能。但它在这里实现了什么<不管怎样,code>ls
仍将完成读取大量名称的所有工作。ls-A
将把整个目录读取到内存中,并在输出第一行之前对其进行排序。管道通过头部的优点是bash不需要全部读取(例如,考虑大型邮件)。缺点是它正在启动另一个进程。也许ls-AU
会立即启动输出?也许if!ls-AU | read |;然后回应“它是空的”;fi
一些解释就好了
[ -z "$(find "$DIR" -maxdepth 0 -empty)" ] || echo "$DIR is empty!"
[ -n "$(find "$DIR" -maxdepth 0 -empty)" ] && echo "$DIR is empty!"
if ! ls -AU "$DIR" | read _; then
echo "$DIR is empty!"
fi