findコマンドで「一重引用符」を使用することと「一重引用符」を使用しないことの違いは何ですか?

findコマンドで「一重引用符」を使用することと「一重引用符」を使用しないことの違いは何ですか?
find ~/ -name *test.txt
find ~/ -name '*test.txt'

最初のフォームは失敗しますが、2番目のフォームはまだ機能する例を作成する必要があります。

答え1

引用符はシェルワイルドカード拡張からコンテンツを保護します。そのコマンドを実行すると(または単純にファイルがあるディレクトリで実行echo *test.txtfootest.txt、最後にファイルがないディレクトリで実行した場合test.txt)、違いを確認できます。

$ ls
a  b  c  d  e
$ echo *test.txt
*test.txt
$ touch footest.txt
$ echo *test.txt
footest.txt

検索でも同じことが起こります。

$ set -x
$ find . -name *test.txt
+ find . -name footest.txt
./footest.txt
$ find . -name '*test.txt'
+ find . -name '*test.txt'
./footest.txt
$ touch bartest.txt
+ touch bartest.txt
$ find . -name *test.txt
+ find . -name bartest.txt footest.txt
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
$ find . -name '*test.txt'
+ find . -name '*test.txt'
./bartest.txt
./footest.txt

答え2

TL;博士版

二重引用符のように、文字列リテラルをコマンド/プログラムに渡しますが、一重引用符を使用すると変数とワイルドカードは拡張されませんが、二重引用符は文字列リテラルに拡張されるという違いがあります。

例:

$ export MY_VAR=my_string
$ echo "$MY_VAR"
my_string
$ echo '$MY_VAR'
$MY_VAR

ワイルドカードにも同様に適用されます。

編集する:

2番目のコマンドと一致するリテラルは、必然的に最初のコマンドのワイルドカードと一致するため、あなたが要求したもののような例は不可能に見えます。

答え3

他の回答を補うために、およびzsh問題fish(t)csh発生する前にエラーを表示するのに役立ちますので、ここでより便利です。

*test.txt現在のディレクトリにファイルがない場合:

zsh$ find . -name *test.txt
zsh: no matches found: *test.txt

fish> find . -name *test.txt
fish: No matches for wildcard '*test.txt'.
find . -name *test.txt
             ^

tcsh> find . -name *test.txt
find: No match.

fishそしてzshこれが正しいことを明確にしなさい。シェル(いいえfind)ここで文句を言うのは、tcshwhileのエラーが誤解を招くということです。 (tcshは見ているNo matchだけですが、みんなコマンドラインのglobは一致しません。一部が一致し、一部が一致しない場合、Bourneのようなシェルのように一致しないものが拡張されます。

以下を使用してbash同じ動作を得ることができます。

$ shopt -s failglob
$ find . -name *test.txt
bash: no match: *test.txt

答え4

最初の場合、パラメータは*test.txtコマンド自体の演算子として扱われ、引用符をfind使用すると、パラメータは*test.txtスイッチのパラメータとして扱われますfind

現在のディレクトリに複数の拡張子を持つテキストファイルがある場合、findは引数を見ることができ.txtないため、次の操作は失敗します*.txt

find . -name *.txt

そしてこれは成功します:

find . -name '*.txt'

関連情報