我们使用以下方法来验证文件夹是否为空:
[[ "$(ls -A /var/folder)" ]] && echo "not empty"
在 上/var/folder
,我们执行了以下操作:
ls -l /var/folder
total 0
事实上我们没有得到任何输出。
但是当我们运行 shell 时
[[ "$(ls -A /var/folder)" ]] && echo "not empty"
然后它打印
not empty
所以我们发现该文件夹包含带有前导点的文件,如下所示:
ls -la /var/folder
total 4
drwxr-xr-x 2 kafka kafka 47 Jan 19 17:23 .
drwxr-xr-x 42 kafka kafka 4096 Jan 19 10:25 ..
-rw-r--r-- 1 kafka kafka 0 Jan 19 17:22 .kafka_cleanshutdown
-rw-r--r-- 1 kafka kafka 0 Jan 19 15:16 .lock
所以问题是如何验证文件夹是否为空但忽略以“.”开头的文件的存在。
答案1
如果您不想看到点文件,请忽略-A
!
[[ "$(ls /var/folder)" ]] && echo "not empty"
但你甚至不需要使用ls
;您可以完全在 shell 中执行此操作:
file_list=(/var/folder/*)
[[ "${file_list[*]}" != "/var/folder/*" ]] && echo "not empty"
这扩展了/var/folder/*
通配符模式(“glob”)。如果有非隐藏文件,那么file_list
将是它们的名称列表。如果没有,则file_list
只是文字 string /var/folder/*
。
这里有一个错误:如果目录包含一个名称为literal的文件*
,那么${file_list[*]}
将是文字字符串/var/folder/*
,上面的代码将失败(表明该目录为空)。你可以通过这样做来解决这个问题
shopt -s nullglob
file_list=(/var/folder/*)
[[ "${file_list[*]}" != "" ]] && echo "not empty"
shopt -u nullglob
当然,强大的脚本会在开始时检查设置nullglob
,然后在最后恢复该设置,而不是仅仅取消设置。
这是为 bash 编写的,不适用于所有 shell。
答案2
您可以展开*
目录并计算它匹配的名称数量。如果它匹配零个名称,则该目录为空。默认情况下,该*
模式与隐藏名称(“带有前导点的文件”)不匹配。
shopt -s nullglob
set -- /var/folder/*
if [ "$#" -eq 0 ]; then
echo '/var/folder is empty'
fi
"$#"
是位置参数列表中的元素数量,我们将其设置为set
相关目录中的可见名称。
如果您愿意,您bash
可以使用数组:
shopt -s nullglob
names=( /var/folder/* )
if [ "${#names[@]}" -eq 0 ]; then
echo '/var/folder is empty'
fi
unset -v names
我们nullglob
在上面的代码片段中设置,如果模式不匹配任何内容,则将其完全删除。不使用 using 的更便携的变体nullglob
是像第一个变体一样使用set
,然后测试$1
是否存在:
set -- /var/folder/*
if [ ! -e "$1" ] && [ ! -h "$1" ]; then
echo '/var/folder is empty'
fi
请注意,我们需要测试-h
in 中的名称是否$1
是符号链接,否则我们将无法检测损坏的符号链接。