拡張されていないアスタリスクによるエラーの回避


16

bashでは、次のようなforループをよく使用します

for file in *.type; do 
  sommecommand "$file"; 
done;

に一致するすべてのファイルに対して操作を実行します*.type。作業ディレクトリにこの末尾のファイルが見つからない場合、アスタリスクは展開されず、通常、コマンドがファイルを見つけられなかったというエラーメッセージが表示されます。このエラーを回避するいくつかの方法をすぐに考えられます。ただし、条件を追加してもそれほどエレガントではないようです。これを達成するための短くてきれいな方法はありますか?

回答:


20

はい、次のコマンドを実行します。

shopt -s nullglob

一致を無効にし、エラーはトリガーされません。

  • デフォルトでこの動作が必要な場合は、コマンドを ~/.bashrc
  • POSIXシェルでヌルグロブを検出する場合は、試してください

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done

http://mywiki.wooledge.org/NullGlobを参照してください


1
というファイルを実際に持つことができることに注意してください*.txt。ファイルが存在するかどうかを確認する価値があります。
クリスダウン

それに応じて編集された投稿。
ジルケノー

@ChrisDownあなたの答えと同じコメントがここに適用されることに注意してください(のbreak代わりに、より深刻な結果になる可能性がありますcontinue)。
ステファンシャゼル

6

bashではshopt -s nullglob、一致するものがない場合は、空の配列に展開するために使用できます。

なしのPOSIXシェルでは、ループの最初の部分としてnullglob渡すことで、渡されるファイル名が実際に存在することを確認することにより、この問題を回避できます。[ -e "$file" ] || [ -L "$file" ] || continuefor


1
[ -eアクセスできないファイル、またはアクセスできないファイルや存在しないファイルへのシンボリックリンクであるファイルに対してfalseを返すため、厳密に同等ではないことに注意してください。
ステファンシャゼル

@StephaneChazelas、シンボリックリンクに関するポイントを認めましょう。しかし、「アクセスできないファイル」によって何を念頭に置いていますか?私はあってもchmod 0 the_file[ -e the_file ]それは何か他のものでなければならないので、まだ、真と評価します。
-dubiousjim

1
壊れたシンボリックリンクを処理するために編集を送信しました。大丈夫だと思います。
-dubiousjim

2
@dubiousjim 、mkdir -p x/{a,b} && chmod 444 x && echo x/* && [ -e x/a ]. x / aはアクセスできませんが、xが読み取り可能であるため、x / *は拡張されます。
ステファンシャゼル

@StephaneChazelas、説明してくれてありがとう。
-dubiousjim

4

nullglobオプションのないシェルの通常のテクニックは

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

余分なの[*].type*.type、現在のディレクトリで1つのファイルが呼び出される場合をカバーすることです。

これで、ドットファイルを含める場合は、より複雑になります。

数年前にusenetでLaura Fairheadがこの技術を生み出したと信じています。


0

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

これにより、forループとシェルのグロビングが方程式から完全に削除されます。一致ごとに1回コマンドfindを実行し、-exec一致がない場合は実行されません。-maxdepth 0指示するには、(指定されたパス引数のサブディレクトリに再帰的ではないことを見つける.、この場合には、)。

欠点は、そこに存在する事実上すべてのLinuxシステム(およびおそらくほとんどのUnix)に存在するにもかかわらず、別のアプリケーションが関与することです。

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