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


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

回答:


5

それらがすでにディレクトリであると予想し、それらがすべて存在するかどうかを確認しているだけの場合は、lsユーティリティの終了コードを使用して、1つ以上の「エラーが発生した」かどうかを判断できます。

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/…を
Jeff Schaller

まだ構文がどのように機能するかを理解しようとしています。&>filenamestdoutとstderrの両方をリダイレクトすることを読んだfilename。したがって、コマンドを簡略化できませんでした(少なくとも、私にとってはより単純です)ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir2" &>/dev/null && echo All there
エレガンス

3
(1)あなたはおそらく-dオプション(a)を使うべきですlsディレクトリーを統計するだけで読み取りは不要です。(b)ユーザーがディレクトリーへの読み取りアクセス権を持っていない場合でもコマンドは成功します。(2)"$PWD/"名前が始まるディレクトリを防ぐ以外に使用する理由はありません-(もちろん、より良い方法があります)。
G-Manは 'Reinstate Monica'を

1
このコマンドは、元の質問のテストよりも実行にかなり時間がかかる可能性があります。また、ディレクトリをチェックしません。
Jasen

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

これはバッシュです。よりポータブルなものは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
ジェフシャラー

5
また、POSIXは次の使用を推奨していません-a: " -aおよび-oバイナリプライマリ(...)演算子は廃止予定
Elegance

@JeffSchallerテストの1回の呼び出しですべてを実行するため、より簡潔です。
デビッドコンラッド

2
まったく同じではありません。元の呼び出しtest(別名[)は3回、これは1回呼び出します
Jasen

1
pubs.opengroup.org/onlinepubs/9699919799/utilities/…は、POSIXステートメントの場所へのより正確な参照です。
G-Manは 'Reinstate Monica'

4

質問に従って、複数のディレクトリの存在と非存在をテストする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

1

目標は、いくつかのディレクトリの存在と他の  ディレクトリの非存在を確認することです 【エンファシス追加】

上の建物グレン・ジャックマンの答えは、我々はこのような他の名前が存在しないためにテストすることができます。

result = True
\のdir
        "$ PWD / dir1" \
        "$ PWD / dir2" \
        「$ PWD / dir3」 
行う
    もし![-d "$ dir"]; その後
        result = False
        ブレーク
    fi
終わった
\のdir
        "$ PWD / dir4" \
        "$ PWD / dir5" \
        「$ PWD / dir6」 
行う
    if [-e "$ dir"]; その後#注:いいえ「!」
        result = False
        ブレーク
    fi
終わった 
エコー「$結果」
私は存在する[ -e "$dir" ]かどうかをテストするために使用しました"$dir"。つまり、dir5存在するがファイルの場合、結果はになりFalseます。2番目のグループの名前がディレクトリかどうかをテストするだけの場合[ -d "$dir" ]は、最初のループと同様に、を使用します。

現在の作業ディレクトリにあるものの存在を確認することについて話しているので、おそらく$PWD/名前を指定する必要はありません。するだけ

\のdir
        「dir1」\
        「dir2」\
        「dir3」 
行う
      ︙

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.