bash +フォルダが空であることをテストしますが、前にドットがあるファイルは除外します。

bash +フォルダが空であることをテストしますが、前にドットがあるファイルは除外します。

次の方法を使用して、フォルダが空であることを確認します。

[[ "$(ls -A /var/folder)" ]] && echo "not empty"

で、/var/folder我々は以下を行った。

ls -l /var/folder
total 0

実際、我々は何の結果も得られない。

しかし、シェルを実行すると

[[ "$(ls -A /var/folder)" ]] && echo "not empty"

その後、印刷されます。

not empty

だから私たちは、フォルダに次の点があるファイルが含まれていることを発見しました。

ls -la /var/folder
total 4
drwxr-xr-x  2 kafka kafka   47 Jan 19 17:23 .
drwxr-xr-x 42 kafka kafka 4096 Jan 19 10:25 ..
-rw-r--r--  1 kafka kafka    0 Jan 19 17:22 .kafka_cleanshutdown
-rw-r--r--  1 kafka kafka    0 Jan 19 15:16 .lock

したがって、問題は、フォルダが空であることを確認しながら、「.」で始まるファイルの存在を無視する方法です。

答え1

ドットファイルを見たくない場合は無視してください-A

[[ "$(ls /var/folder)" ]] && echo "not empty"

しかし、使用する必要さえありませんls。シェルで完全に実行できます。

file_list=(/var/folder/*)
[[ "${file_list[*]}" != "/var/folder/*" ]] && echo "not empty"

これは/var/folder/*ワイルドカードパターン(「glob」)を拡張します。非表示のファイルがある場合は、file_listそのファイルの名前のリストになります。そうでなければ、それはfile_listリテラル文字列にすぎません/var/folder/*

ここにはバグがあります。ディレクトリにリテラル文字列となるliteral*というファイルが含まれている場合、上記のコードは失敗します(ディレクトリが空であることを示します)。次の手順でこの問題を解決できます。${file_list[*]}/var/folder/*

shopt -s nullglob
file_list=(/var/folder/*)
[[ "${file_list[*]}" != "" ]] && echo "not empty"
shopt -u nullglob

もちろん、強力なスクリプトは設定を最初に確認してnullglobから、キャンセルするのではなく最後に復元します。

これはbash用に書かれており、すべてのシェルで機能するわけではありません。

答え2

*ディレクトリを展開し、一致する名前の数を数えることができます。名前がゼロと一致する場合、ディレクトリは空です。デフォルトでは、この*パターンは隠された名前(「先頭の点を持つファイル」)と一致しません。

shopt -s nullglob

set -- /var/folder/*

if [ "$#" -eq 0 ]; then
    echo '/var/folder is empty'
fi

"$#"set関連ディレクトリに表示される名前に設定した位置引数リストの要素数。

必要に応じてbash配列を使用できます。

shopt -s nullglob

names=( /var/folder/* )

if [ "${#names[@]}" -eq 0 ]; then
    echo '/var/folder is empty'
fi

unset -v names

nullglobパターンが何も一致しない場合は、完全に削除されるように上記のスニペットで設定しました。を使用しないより移植性に優れたバリエーションは、最初のバリアントのようnullglobに使用してから存在するかどうかをテストすることです。set$1

set -- /var/folder/*

if [ ! -e "$1" ] && [ ! -h "$1" ]; then
    echo '/var/folder is empty'
fi

-h名前がシンボリックリンクかどうかをテストする必要があります$1。そうしないと、壊れたシンボリックリンクを検出できません。

関連情報