我有以下 bash 脚本:
if ls /Users/david/Desktop/empty > /dev/null
then
echo 'yes -- files'
else
echo 'no -- files'
fi
如果目录中有一个或多个文件,我将如何修改第一行,使其评估结果为 true/Users/david/Desktop/empty
dir?
这在Bash常见问题解答#004 http://mywiki.wooledge.org/BashFAQ/004。尤其,use of ls为此目的是一种反模式,应该避免 http://mywiki.wooledge.org/ParsingLs.
shopt -s dotglob # if including hidden files is desired
files=( "$dir"/* )
[[ -e $files || -L $files ]] && echo "Directory is not empty"
[[ -e $files ]]
实际上并不检查整个数组的内容是否存在;相反,它检查返回的第一个名称——它处理没有文件匹配的情况,其中 glob 表达式本身作为唯一结果返回。
Notably:
- This is 快得多比调用
ls
,这需要使用fork()
生成一个子shell,execve()
将该子 shell 替换为/bin/ls
,操作系统的动态链接器加载所使用的共享库ls
二进制文件等。 [一个例外是包含数万个文件的非常大的目录——在这种情况下ls
也会很慢;看到find
基于下面的解决方案]。
- This is 更正确比调用
ls
:保证由 globbing 返回的文件列表与文件的字面名称完全匹配,而ls
可以修改带有隐藏字符的名称。如果第一个条目是有效的文件名,"${files[@]}"
可以安全地迭代,并确保每个返回值都是一个名称,并且无需担心名称中带有文字换行符的文件系统会增加计数(如果本地)ls
实施并没有逃避他们。
也就是说,另一种方法是使用find
,如果你有一个-empty
扩展(可从 GNU find 和现代 BSD(包括 Mac OS)获得):
[[ $(find -H "$dir" -maxdepth 0 -type d -empty) ]] || echo "Directory is not empty"
...if any给出结果,目录非空。虽然比在不是特别大的目录上进行通配要慢,但这比either ls
或通配查找目录缓存中不存在的极大目录,因为它可以在不进行完整扫描的情况下返回结果。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)