3つのファイル形式がすべてディレクトリにあるかどうかをテストします。

3つのファイル形式がすべてディレクトリにあるかどうかをテストします。

.png.txt次のファイル形式のいずれかがディレクトリに存在するかどうかを検出したいと思います.tar.gz

次のいずれかをテストしたときに正しく機能しました。

shopt -s nullglob
MYDIR=/some_dir
if [ $MYDIR/*.png] && [ $MYDIR/*.txt]; then
  echo "All files present"
else
  echo "At least one type is missing"
fi

しかし、次のように3つすべてをテストしようとすると

if [ $MYDIR/*.png] && [ $MYDIR/*.txt] && [ $MYDIR/*.tar.gz]; then
...

または使用

if [[ $MYDIR/*.png && $MYDIR/*.txt && $MYDIR/*.tar.gz ]]; then
...

まあ、正しい動作は発生しません(ファイルのいずれかが欠落している場合でもまだtrueを返します)。

ここで何が起こっているのでしょうか?

ベストアンサー1

ファイル名のワイルドカードパターンが一致するかどうかをテストすることはできません(そして、[ ... ]すべてのテストで最後のスペースの前にスペースがありません。コードが機能しません)。][ ... ]

方法は、一致を実行し、一致する名前の数を数えることです。

shopt -s nullglob    # make globs expand to nothing if they don't match
shopt -s dotglob     # also match hidden names

error=false
for ext in png txt tar.gz; do
    set -- "$MYDIR"/*."$ext"
    if [ "$#" -eq 0 ]; then
        printf 'Nothing matches "%s"\n' "$MYDIR/*.$ext" >&2
        error=true
        break  # possibly, unless you want the user to see all patterns that fail
    fi
done

if "$error"; then
    echo 'Can not continue' >&2
    exit 1
fi

より多くを入力したい場合、または既存の位置引数のリストを保持したい場合は、名前付き配列を使用できます。set --行をnames=( "$MYDIR"/*."$ext" )および"$#"に変更します"${#names[@]}"。すべての引用符が重要です。

おすすめ記事