引数として「-」で始まるファイルをBash拡張が渡さないようにするにはどうすればよいですか?


14

私は文字列を再帰的に検索しようとしていますがgrep、これが得られます:

$ grep -r "stuff" *
grep: unrecognized option '---corporate-discount.csv'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

Bashが-引数として始まるファイルを渡さないようにするにはどうすればよいですか?



3
シェルがこれらのファイルを渡さないようにしたくないのですか?問題はgrep、それらがオプションではないことをどのように伝えるかということです。
ドンホルゴ

11
...明確にするために、bashはオプションとして扱われる結果と引数として扱われる結果を制御しません。それは受信プログラムの制御下にあります。たとえば、subprocess.Popen(['grep', '-r', '-e' 'stuff', '--corporate-discount.csv'])Pythonではどこにもbashがなくても同じ動作をします。
チャールズダフィー

1
関連資料:Unix Wildcards Gone Wild*inコマンドの使用により発生する可能性があるセキュリティ問題について。これらのすべては、./*代わりに使用することで回避できます。
ワイルドカード

1
@Wildcardは、--オプションの最後にsigilを使用することも完全に合理的です。POSIXユーティリティの構文ガイドラインでは、遵守する必要があります。ガイドライン#10を参照してください。(確かに、すべてのプログラムがPOSIXガイドラインに従っているわけではありませんが、答えは問題のあるプログラムの作者をつなぎとめるか、業界から排除することです)。
チャールズダフィー

回答:


43

最初に、ダッシュで始まる引数の解釈は、開始されるプログラムgrepまたは他のユーザー次第であることに注意してください。シェルには直接制御する方法がありません。

そのようなファイルを処理したい(そしてそれらを完全に無視しない)と仮定するとgrep、ほとんどのプログラムとともに、--、オプションの終わりを示すものとしてします。

grep -r -e "stuff" -- *

あなたが望むことをします。の-estuff始まる場合-もあります。

または、次を使用することもできます。

grep -r -e "stuff"  ./*

後者-は、現在のディレクトリにファイルが呼び出された場合にも問題を回避できます。--区切り文字の後でも、stdinを意味しているとgrep解釈さ-./-ますが、ファイル-は現在のディレクトリで呼び出されます。


8

Bash拡張が「-」で始まるファイルを渡さないようにするには次を使用できます。

echo [!-]*

これは、ほとんどのシェル、またはksh、bash、zshに固有の移植性のある機能です。

echo !(-*)

例:このファイルがあるディレクトリ内

$ echo *
a b c ---corporate-discount.csv d -e --option.txt

リストのみ(extglobアクティブな場合):

$ shopt -s extglob
$ echo !(-*)
a b c d

$ echo [!-]*
a b c d

しかし、-オプションとして指定されたファイルを解釈しないようにgrepに指示しながらすべてのファイルを処理する場合は、単に追加し./ます:

grep -r "stuff" ./*

または、-リストされたファイルに正確に呼び出されたファイルが存在しないことが保証されている場合(grepはstdinからの読み取り-として孤独を解釈します)、以下を使用できます。

grep -r -- "stuff" *

はい、質問はGNUシェルであるbashに関するものなので、GNU grepが利用可能、インストール可能、または実際に使用されていると想定するのは合理的です。@StéphaneChazelas–
アイザック

はい、a grep -r -- stuff *はよりシンプルで、GNUish以外のgrepsでも動作します。だから、追加、ありがとう。@StéphaneChazelas–
アイザック

@Isaac「bashが利用可能であれば、GNU grepも利用可能」という合理的な仮定とは言いません。例えば、FreeBSD:bashはデフォルトはインストールされませんが、後でインストールできますが、grepには影響がありません-GNU grepが明示的にインストールされない限り、grepのBSDバージョンのままです。しかし、それは些細なことです。私はextglobを介した代替アプローチが好きなので、答えを+1しました
Sergiy Kolodyazhnyy

2
grepFreeBSD上のAFAIKの@SergiyKolodyazhnyyは、まだGNUに基づいてgrepおり、まだオプションが非オプションの後に認識されるという誤った特徴を持っています。書き直されたOpenBSDのようなBSDでさえgrep、後方互換性のためにGNU互換にしました(そして、ここでもその動作を示しています)。macOSでは、shはbashです。しかし、macOSは$ POSIXLY_CORRECTがなくてもPOSIX準拠であることを意図しているため、grepがその動作を示さないことを期待しています。いずれにせよ、OPのgrep そのエラーを与えるためGNU互換です。
ステファンシャゼル

1
echo [!-]*ksh(またはbash -O extglob)の標準的な同等物としても参照してくださいecho !(-*)
ステファンシャゼル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.