2009-08-21 14 views
3

ディレクトリにファイルがあるかどうかをbashにチェックします。 私のコードはこちらです。ファイル名展開の結果をbashでテストする方法は?

for d in {,/usr/local}/etc/bash_completion.d ~/.bash/completion.d 
    do    
     [ -d "$d" ] && [ -n "${d}/*" ] &&       

     for f in $d/*; do                           
      [ -f "$f" ] && echo "$f" && . "$f"       

     done                               
    done 

"〜/ .bash/completion.d"にはファイルがありません。 したがって、$ d/*は単純な文字列 "〜/ .bash/completion.d/*"とみなされ、ファイル名の拡張の結果である空の文字列ではありません。 そのコードの結果として、bashは

. "~/.bash/completion.d/*" 

を実行しようとすると、もちろん、それはエラーメッセージを生成します。

誰かが私を助けることができますか?

+0

単純な言葉では、無効なファイル名文字列のファイル名拡張を強制する方法を知りたいです。 – user159087

答えて

6

あなたはnullglobのbashのオプションを設定した場合、

shopt -s nullglob 

て、その後グロブは、任意のファイルを一致しないパターンをドロップします。

+0

kjshimのコードは 'nullglob'(' shopt nullglob'が "off"を返す)を設定せずにそのまま動作しているようです。それが何であるか、どんなアイデアですか? –

+0

おそらくあなたが試していたディレクトリは空ではありませんでしたか? –

+0

'ls -la test'は' .'と '..'を表示します –

0

あなたは次のように直接findを使用することができます。

for f in $(find {,/usr/local}/etc/bash_completion.d ~/.bash/completion.d -maxdepth 1 -type f); 
do echo $f; . $f; 
done 

しかしfindは、ディレクトリの一部が見つからない場合、あなたは2> /dev/nullを置くか、テストの後findコールを置くことができるいずれかの警告を出力しますあなたのコードのようなディレクトリが存在する場合。

0
find() { 
for files in "$1"/*;do 
    if [ -d "$files" ];then 
     numfile=$(ls $files|wc -l) 
     if [ "$numfile" -eq 0 ];then 
      echo "dir: $files has no files" 
      continue 
     fi 
     recurse "$files" 
    elif [ -f "$files" ];then 
     echo "file: $files"; 
     : 
    fi 
done 
} 
find /path 
+0

Pretty code。それは何をするためのものか? –

0

別のアプローチ

# prelim stuff to set up d 
files=`/bin/ls $d` 
if [ ${#files} -eq 0 ] 
then 
    echo "No files were found" 
else 
    # do processing 
fi 
4
 
# NOTE: using only bash builtins 
# Assuming $d contains directory path 

shopt -s nullglob 

# Assign matching files to array 
files=("$d"/*) 

if [ ${#files[@]} -eq 0 ]; then 
    echo 'No files found.' 
else 
    # Whatever 
fi 

アレイへの割当は、サブを使用せずにホワイトスペース、および単純な反復を含むファイル名/パスの望ましい(正しい!)処理を含む他の利点を有しています次のコードのように-shellを使用します。

 
find "$d" -type f | 
while read; do 
    # Process $REPLY 
done 

代わりに、

 
for file in "${files[@]}"; do 
    # Process $file 
done 

ループがメインシェルによって実行されるという利点があります。つまり、ループ内で行われた副作用(変数の割り当てなど)がスクリプトの残りの部分で表示されることを意味します。もちろん、性能が問題であれば、ウェイの方が高速です。
最後に、アレイはまた、(空白を含む分割引数なし)コマンドライン引数に挿入することができます。

 
$ md5sum fileA "${files[@]}" fileZ 

あなたは常に正しく、ホワイトスペースを含むファイル/パスを処理しようとする必要があり、1日のため、 、彼らは起こります!

+0

ファイルのグロブ展開の良い例では、bashマニュアルはその部分で非常に混乱しています! –

関連する問題