web-dev-qa-db-ja.com

複数のディレクトリの存在を確認する

複数のディレクトリの存在を確認したい、たとえばdir1dir2およびdir3、作業ディレクトリ。

私は以下を持っています

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

しかし、私はこれを行うよりエレガントな方法があると思います。ディレクトリの名前にパターンがあると仮定しないでください。

目標は、いくつかのディレクトリの存在と他のディレクトリの非存在を確認することです。

私はBashを使用していますが、移植可能なコードが推奨されます。

8
Elegance

それらがディレクトリであることをすでに予期していて、それらがすべて存在するかどうかを確認しているだけであれば、lsユーティリティの終了コードを使用して、1つ以上の "errors occurred" かどうかを判断できます。

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

出力とstderrを/dev/nullにリダイレクトして、出力を非表示にします。これは、出力ではなくlsからの終了コードのみを考慮するためです。 /dev/nullに書き込まれたものはすべて消えます—端末には書き込まれません。

5
Jeff Schaller

私はループします:

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

breakは、&&のチェーンと同様に、ループを短絡させます。

9
glenn jackman

ループはよりエレガントかもしれません:

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

これはバッシュです。よりポータブルなものはShです。そこでは、位置配列を使用できます。

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

次に、ループオーバーするには"$@"を使用します。

5
user147505

なぜか:

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

質問に従って、複数のディレクトリの存在と非存在をテストする2つの移植可能なシェル関数:

# 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
4
Kusalananda