複数のディレクトリの存在を確認したい、たとえばdir1
、dir2
およびdir3
、作業ディレクトリ。
私は以下を持っています
if [ -d "$PWD/dir1" ] && [ -d "$PWD/dir2" ] && [ -d "$PWD/dir3" ]; then
echo True
else
echo False
fi
しかし、私はこれを行うよりエレガントな方法があると思います。ディレクトリの名前にパターンがあると仮定しないでください。
目標は、いくつかのディレクトリの存在と他のディレクトリの非存在を確認することです。
私はBashを使用していますが、移植可能なコードが推奨されます。
それらがディレクトリであることをすでに予期していて、それらがすべて存在するかどうかを確認しているだけであれば、ls
ユーティリティの終了コードを使用して、1つ以上の "errors occurred" かどうかを判断できます。
ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir3" >/dev/null 2>&1 && echo All there
出力とstderrを/dev/null
にリダイレクトして、出力を非表示にします。これは、出力ではなくls
からの終了コードのみを考慮するためです。 /dev/null
に書き込まれたものはすべて消えます—端末には書き込まれません。
私はループします:
result=True
for dir in \
"$PWD/dir1" \
"$PWD/dir2" \
"$PWD/dir3"
do
if ! [ -d "$dir" ]; then
result=False
break
fi
done
echo "$result"
break
は、&&
のチェーンと同様に、ループを短絡させます。
ループはよりエレガントかもしれません:
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"
次に、ループオーバーするには"$@"
を使用します。
なぜか:
if [ -d "dir1" -a -d "dir2" -a -d "dir3" ]; then
echo True
else
echo False
fi
質問に従って、複数のディレクトリの存在と非存在をテストする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