【发布时间】:2010-11-23 07:25:56
【问题描述】:
我有一个问题
我尝试了一些类似的功能
DIR=/path/tmp/
如果 [ -d "$DIR" ];那么
和
如果 [ -f "$DIR" ];那么
但只检查 /path/tmp 这个路径
我该怎么办?
【问题讨论】:
我有一个问题
我尝试了一些类似的功能
DIR=/path/tmp/
如果 [ -d "$DIR" ];那么
和
如果 [ -f "$DIR" ];那么
但只检查 /path/tmp 这个路径
我该怎么办?
【问题讨论】:
rmdir "$DIR"
如果$? 为1,则目录不为空。如果为 0,则为空并被删除。
如果您不打算删除它,可以重新创建它:mkdir "$DIR"
【讨论】:
shopt -s nullglob dotglob
files=(*)
(( ${#files[*]} )) || echo directory is empty
shopt -u nullglob dotglob
这个小脚本用在路径扩展* 中找到的每个文件填充数组files。然后它会检查数组的大小,如果它为 0,则打印“目录为空”。由于使用了dotglob,这将适用于隐藏文件。
要求解析ls 的答案通常是一个坏主意和糟糕的形式。要了解原因,请阅读Why you shouldn't parse the output of ls
【讨论】:
ls 解决方案,但请注意我的答案不 解析ls 的输出。它只是检查它是否有。 :-)
[ -z "$(find "$DIR" -maxdepth 0 -empty)" ] || echo "$DIR is empty!"
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
【讨论】:
您可以为此使用ls -A:
if [ "$(ls -A "$DIR" 2> /dev/null)" == "" ]; then
# The directory is empty
fi
-A 显示除了始终存在的. 和.. 之外的所有隐藏文件和目录,因此它在空目录中为空白,在包含任何文件或子目录的目录中为非空白。
2> /dev/null 丢弃ls 可能打印的任何错误消息(请注意,检查不存在的目录会产生误报,但您说您已经检查过它存在)。检查您没有读取权限的目录也会产生误报。
【讨论】:
... [ "$(ls -A "$DIR" 2>/dev/null | head -n 1)" == "" ] ...
| head -n 1 真的有什么帮助吗? ls 仍然会生成完整列表,不是吗?
| head -n 1 将从ls 中取出第一行,输出它然后切断输入 - 即它说“这就够了!”还有一个很好的解决方案,用read 代替head - 试试| read 并检查退出代码。
head 做了什么。但它在这里实现了什么?不管怎样,ls 仍将完成读取大量姓名的所有工作。
ls -A 会将整个目录读入内存并在输出第一行之前对其进行排序。通过head 进行管道传输的优点是 bash 不需要读取所有内容(例如考虑大型邮件目录)。缺点是它正在启动另一个进程。也许ls -AU 会立即开始输出?也许if ! ls -AU | read _; then echo 'it's empty'; fi
为什么不使用 ls -v ?所以如果没有诸如
if $(ls -v $DIR)
【讨论】:
-v(“文本中自然排序的(版本)数字”)?速度?
if ls -v $DIR 没有错误,但它总是正确的。你必须做if [ "$(ls -v "$DIR")" ] 或if [[ $(ls -v "$DIR") ]]。如果需要,使用! 反转逻辑。
这告诉我目录是否为空,如果不是,它包含的文件数。
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):
if test "`echo /tmp/testdir/* /tmp/testdir/.?*`" = \
"/tmp/testdir/* /tmp/testdir/.."; then
[...]
fi
我们不检查 /tmp/testdir/.*,因为它会扩展到 /tmp/testdir/。 /tmp/testdir/.. 为空文件夹。
另一个仅内置的变体:
for i in /tmp/testdir/* /tmp/testdir/.?*; do
test -e $i || break
[...]
break
done
【讨论】: