检查是否存在多个目录


8

我要检查多个目录的存在,说dir1dir2并且dir3,在工作目录。

我有以下

if [ -d "$PWD/dir1" ] && [ -d "$PWD/dir2" ] && [ -d "$PWD/dir3" ]; then
    echo True
else
    echo False
fi

但是我怀疑这样做有更优雅的方法。不要假定目录名称中存在模式。

目的是检查一些目录是否存在以及其他目录是否不存在。

我正在使用Bash,但首选可移植代码。


1
“目标是检查一些目录是否存在以及其他目录是否不存在。” 好,您的示例检查所有列出的目录是否存在。您能详细说明一下吗?是全部列出还是任何列出?您是否需要检查传递的值实际上是目录,而不是其他类型的文件?
Sergiy Kolodyazhnyy

1
$PWD顺便说一下,您不需要。[ -d "$PWD/dir1"]等同于[ -d "dir1" ]
terdon

Answers:


5

如果您已经期望它们是目录,并且只是在检查它们是否全部存在,则可以使用ls实用程序中的退出代码来确定是否发生了一个或多个“错误”

ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir3" >/dev/null 2>&1 && echo All there

我将输出和stderr重定向/dev/null到以使其消失,因为我们只关心的退出代码ls,而不关心它的输出。写入的所有内容都会/dev/null消失-不会写入您的终端。


你能帮我理解这个命令吗?我知道什么是文件描述符。我知道1是stdout,2是stderr,我知道重定向是什么。我不了解的含义/dev/null,也不知道如何解析命令。
优雅

@优雅我加了一点解释。有关更深入的答案的/ dev / null的,见unix.stackexchange.com/questions/163352/...unix.stackexchange.com/questions/438130/...
杰夫·夏勒

仍在尝试弄清楚语法如何工作。我读到&>filename将stdout和stderr都重定向到filename。因此,不能将命令简化为(至少对我来说更简单)ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir2" &>/dev/null && echo All there吗?
优雅

3
(1)您可能应该使用-d选项(a),因此ls仅需统计目录,而不需要读取目录,以及(b),即使用户没有对目录的读取权限,命令也将成功执行。(2)"$PWD/"除了保护名称以其开头的目录-(当然,还有更好的方法)之外,我看不出有任何其他理由要使用。
G-Man说'Resstate Monica''Mar

1
该命令可能比原始问题中的测试花费更长的时间。也不会检查目录。
詹森

9

我会循环:

result=True
for dir in \
        "$PWD/dir1" \
        "$PWD/dir2" \
        "$PWD/dir3" 
do
    if ! [ -d "$dir" ]; then
        result=False
        break
    fi
done
echo "$result"

break导致循环短路,就像你的链&&


5

循环可能更优雅:

arr=("$PWD/dir1" "$PWD/dir2" "$PWD/dir2")
for d in "${arr[@]}"; do
    if [ -d "$d"]; then
        echo True
    else
        echo False
    fi
done

这是Bash。Sh是一种更便于携带的产品。在那里,您可以使用位置数组:

set -- "$PWD/dir1" "$PWD/dir2" "$PWD/dir2"

然后使用循环"$@"


5

为什么不只是:

if [ -d "dir1" -a -d "dir2" -a -d "dir3" ]; then
    echo True
else
    echo False
fi

这基本上就是OP的开始But I suspect there is a more elegant way of doing this
Jeff Schaller

5
POSIX 还不鼓励使用-a:“ -a-o二进制主(...)运算符已被标记为过时”:pubs.opengroup.org/onlinepubs/9699919799
优雅

@JeffSchaller更为简洁,因为它一次调用即可完成所有工作。
戴维·康拉德

2
根本不一样,原始调用一次test(aka [)三次调用一次,
Jasen


4

根据问题,两个可移植的shell函数测试多个目录的存在和不存在:

# Returns success if all given arguments exists and are directories.
ck_dir_exists () {
    for dir do
        [ -d "$dir" ] || return 1
    done
}

# Returns success if none of the given arguments are existing directories.
ck_dir_notexists () {
    for dir do
        [ ! -d "$dir" ] || return 1
    done
}

例:

$ mkdir dir1 dir2
$ ck_dir_exists dir1 dir2; echo $?
0
$ ck_dir_exists dir1 dir2 dir3; echo $?
1
$ ck_dir_notexists dir1 dir2 dir3; echo $?
1
$ ck_dir_notexists dir3 dir4; echo $?
0

1

目的是检查一些目录是否存在以及其他  目录 是否不存在。[强调已添加]

glenn jackman的答案为基础,我们可以测试是否存在其他这样的名称:

结果=真
用于\
        “ $ PWD / dir1” \
        “ $ PWD / dir2” \
        “ $ PWD / dir3” 
做
    如果![-d“ $ dir”]; 然后
        结果=假
        打破
    科幻
做完了
用于\
        “ $ PWD / dir4” \
        “ $ PWD / dir5” \
        “ $ PWD / dir6” 
做
    如果[-e“ $ dir”]; 然后#注:不“!”
        结果=假
        打破
    科幻
完成 
echo“ $ result”
我曾经[ -e "$dir" ]测试是否"$dir"存在。即,如果dir5存在但为文件,则结果为False。如果只想测试第二组中的名称是否是目录[ -d "$dir" ],请像在第一个循环中那样使用。

由于我们正在谈论检查当前工作目录中是否存在事物,因此可能不必指定$PWD/名称;做就是了

用于\
        “ dir1”
        “ dir2”
        “ dir3” 
做
      ︙

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.