Answers:
if [ -z "$(ls -A /path/to/dir)" ]; then
echo "Empty"
else
echo "Not Empty"
fi
另外,检查目录是否以前也很酷。
&&
,并||
同时!如果echo "Not Empty"
失败,echo "Empty"
将运行!试试看echo "test" && false || echo "fail"
!是的,我知道echo
不会失败,但是如果您更改任何其他命令,您将会感到惊讶!
[ "$(ls -A /)" ] && touch /non-empty || echo "Empty"
-如果要“标记”具有创建的文件的非空目录non-empty
,将失败并显示“空”。
touch /empty
我的线?
if [ -n "$(ls -A /path/to/dir)" ]; then
...请先更新答案,然后再有人将此代码粘贴到他们的服务器中,然后黑客找出如何利用它。如果/path/to/dir
不为空,那么那里的文件名将作为参数传递,/bin/test
这显然是不希望的。只需添加-n
参数,问题就解决了。谢谢!
无需计算任何东西或外壳球。您也可以read
与结合使用find
。如果find
输出为空,则返回false
:
if find /some/dir -mindepth 1 | read; then
echo "dir not empty"
else
echo "dir empty"
fi
这应该是便携式的。
echo
呼叫反映了错误的结果:在我的测试中(在Cygwin下)find . -mindepth 1 | read
,非空目录中有141错误代码,空目录中有0错误代码
read
返回0,对于空目录,返回
set -o pipefail
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
-n
正确且安全的测试(使用名称中带有空格的目录进行测试,使用名称“ 0 = 1”的非空目录进行测试)。... [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; ...
grep
。serverfault.com/questions/225798/...
find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty | grep .
,并且依赖于grep的退出状态。无论采用哪种方式,这都是解决此问题的正确方法。
#!/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
这将在当前工作目录(。)中完成该工作:
[ `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
(请参阅@Daniel评论)
ls -A
代替。有些文件系统没有.
和..
根据文档的符号链接。
-1
绝对是多余的。即使ls
在管道传输时每行不打印一项,它也不会影响检查是否产生零行或更多行的想法。
使用数组:
files=( * .* )
if (( ${#files[@]} == 2 )); then
# contents of files array is (. ..)
echo dir is empty
fi
shopt -s nullglob
${#files[@]} == 2
假设并不代表根目录(您可能不会测试它是否为空,但是有些代码可能不知道该限制)。
hacky,但仅限bash,无PID的方式:
is_empty() {
test -e "$1/"* 2>/dev/null
case $? in
1) return 0 ;;
*) return 1 ;;
esac
}
这利用了以下事实:test
如果在后面加上多个参数,则内置函数将以2退出-e
:首先,"$1"/*
glob由bash扩展。这导致每个文件一个参数。所以
如果没有文件,则星号test -e "$1"*
不会展开,因此Shell将退回到尝试的名为的文件*
,该文件返回1。
...除非实际上有一个文件精确命名为*
,否则星号会扩展为asterisk,其结果与上述相同,即。test -e "dir/*"
,这一次返回0。(感谢@TrueY指出这一点。)
如果有一个文件,test -e "dir/file"
则运行,返回0。
但是,如果文件多于1,test -e "dir/file1" "dir/file2"
则运行该文件,bash将其报告为使用错误,即2。
case
环绕整个逻辑,以便仅将第一种情况(退出状态为1)报告为成功。
我尚未检查的可能问题:
文件数量超过了允许的参数数量-我猜这可能与2个以上文件的情况类似。
还是实际上有一个文件名是空的-我不确定在任何理智的OS / FS上都可以使用该文件。
test -e dir/*
其调用。如果目录中唯一的文件是“ *”,那么test将返回0。如果有更多文件,则返回2。
使用FIND(1)(在Linux和FreeBSD下),您可以通过“ -maxdepth 0”以非递归方式查看目录条目,并使用“ -empty”测试其是否为空。应用于以下问题:
if test -n "$(find ./ -maxdepth 0 -empty)" ; then
echo "No new file"
exit 1
fi
我认为最好的解决方案是:
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"
即使文件名包含空格,这也将正常工作。
if find "${DIR}" -prune ! -empty -exit 1; then
echo Empty
else
echo Not Empty
fi
编辑:在快速查看实现之后,我认为该解决方案可以与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无效。
编辑:gnu查找没有-exit。对于GNU查找,这应该起作用:
if [ -z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`" ]; then
echo Empty
else
echo Not Empty
fi
这都是很棒的东西-只需将其放入脚本中,这样我就可以检查当前目录下的空目录。将以下内容放入名为“ 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
这项工作对我来说有用,以检查和处理目录中的文件../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
对于当前目录以外的任何目录,您都可以尝试尝试检查其是否为空rmdir
,因为rmdir
对于非空目录,它肯定会失败。如果rmdir
成功,并且您实际上希望空目录在测试中幸存下来,请mkdir
再次执行。
如果他们知道短暂停止存在的目录可能会破坏其他进程,请不要使用此技巧。
如果rmdir
对您不起作用,并且您可能正在测试可能包含大量文件的目录,则任何依赖Shell Globing的解决方案都可能变慢和/或遇到命令行长度限制。find
在这种情况下可能会更好。find
我能想到的最快的解决方案是
is_empty() {
test -z $(find "$1" -mindepth 1 -printf X -quit)
}
它适用于GNU和BSD版本find
的Solaris ,但不适用于Solaris 版本,因为Solaris缺少这些find
运算符中的每一个。热爱您的工作,Oracle。
您可以尝试删除目录并等待错误; 如果目录不为空,则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
rmdir
如果我无权删除目录,将失败;或者它是Btrfs子卷;或者它属于只读文件系统。如果rmdir
没有失败并且mkdir
可以运行:如果已经删除的目录属于另一个用户怎么办?它的(可能是非标准的)权限如何?ACL?扩展属性?全部丢失。