findコマンドの '{}'と{}の違いは?


18

ではドキュメント、私は使い方両方の方法を参照してください。

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \

4
確かに、find、commandとは何の関係もなく、代わりに呼び出されるコマンドの適切な引用と関係があるようです。
ゾレダチェ

1
バッシュではなく、魚で試してみてください。
チャールズダフィー

回答:


24

以下のためのbashシェル、'{}'および{}交換可能です。これは、すべてのシェル(などfish)には当てはまりません。

引数を単一引用符で囲むと、中括弧をに送信する必要があることを明示的に示しますfind。使用法によっては、bashシェルが中括弧の内容を置き換える場合があります。

以下に示すように、bashは空のブラケットを置き換えず、コマンドに渡されます。findコマンドについては、問題ではありません。

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
bashとは関係ありません。魚には関係ありません。
チャールズダフィー

1
私は置き換えたい" are interchangeable"" are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"(あなたはいつも(に起こる場合でも、正しい方法を使用していることを確認して、良い習慣を開始し)あいまいなものを可能にするシステム上にある?)
オリヴィエ・デュラック

9

ほぼすべてのシェルインタープリターを使用できるため、との間にまったく違いは'{}'ありません{}

通常、単一引用符は、埋め込み文字列が他の何かに置き換えられるのを防ぐために使用されます。たとえば、次のとおりです。

  • 'a b' 単一の3文字パラメーターであり、2つの単一文字パラメーターとなる引用符なし
  • '$b' は文字通りドル記号の後に文字bが続きます。変数bに含まれているものは何でも引用符なしで、設定されていない場合は何もありません
  • '!!' 引用符で囲まれていないときのいくつかのインタラクティブなシェルでは、散らかった感嘆符であり、履歴に入れられた最後のコマンドに展開されます
  • '*' は、引用符で囲まれていない、現在のディレクトリにある非表示でないファイル名のリストに置き換えられる、リタラルアスタリスクです。

POSIX標準でも主流のシェルでもないとして(sh(ボーン)、 、kshbashashdash、、zsh 拡大)何か他のものに、引用符は必要ありません。cshtcsh{}

ただし、という名前のエキゾチックなシェルがありfish、これはたまたま{}空の文字列として展開されます。例:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

これがおそらく、GNU findドキュメント{}が引用符やバックスラッシュを使用した解釈から保護することを示唆している理由です。


9

ほとんどのユーザー(特にPOSIXシェルを使用しているユーザー)には違いはありません。

GNUのmanページのExampleセクションによるとfind

中括弧は、シェルスクリプトの句読点として解釈されないように、一重引用符で囲まれていることに注意してください。

GNUのmanページの作者は注意を誤っていると思いますが、manページのすべての例が中括弧を引用しているわけではないことに注意してください。公式のGNU findドキュメントのこれらの例でも、引用は省略されています。

POSIX / Single UNIX Specificationでは、オプションと共に使用する場合、中括弧は引用されません-exec

POSIXシェルでは、パラメーターの展開 は、中かっこで囲まれた特別なパラメーターがある場合にのみ行われますが、空の中かっこでは行われません

Bashシェルには(ポータブルではない)機能としてブレース拡張が含まれていますが、このようなパターンは、ブレース内にコンマまたはドットが含まれている場合にのみ拡張されます。Bashはコマンドのグループ化にも中括弧を使用します、実際に中括弧内にコマンドのグループが存在しない限り、これは発生しません。

最後に、私はランニング試したfind -exec ls -l {} \;中でshdash及びtcshこれらのシェルはいずれも拡張されていない{}他の何かに。他の人が指摘しているように、fishシェルは{}特別に扱いますが、これはPOSIXシェルではありません(作成者とユーザーが利点であると考えています)。これは、中括弧引用する害ませんそれらを省略することについて罪悪感を感じるべきではない魚のシェルを使用しませんが、怠惰なタイピストを。


彼らは間違いではなく、人々が正しい方法を使用することを確認しようとしています(つまり、'{}'代わりに使用する{})、シェルが{}解釈せずにfindコマンドに送信するようにします、それは解釈します{}が、ではない'{}'あなたは、そのシェルの上に後者を使用する必要があるので、そのため、常に使用(および他のいくつかの上に!)。'{}'の曖昧さに刺されることを避けるために{}
オリヴィエ・デュラック

6

これは、シェルの構文に依存します。疑問がある場合は、それをエコーし​​てください!

これを実行する

echo '{}'

この。

echo {}

同じ出力を生成する場合、シェルの答えはイエスです。他の人が指摘したように、少なくともbashではyes、fishではnoです。出力は、特定のコマンドのマンページを参照する必要があるものです。


echo使いやすくしたい場合は、コマンドライン全体にプレフィックスを付けて、シェルが実際に呼び出す実際のコマンドとそのすべての引数を確認することもできます。ただし、コマンドと引数を含むリストは、文字列の真の配列であり、それぞれが空または空白を含む可能性がありますが、エコーはスペース区切りリストとしてあいまいに印刷することに注意してください。

この少し冗長なechoコマンド(guillemetで引用された引数を表示)で確認できるように、

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

コマンドラインでこれを入力して、

find 'My Documents and Settings' -type f -exec file {} \;

これはbashすることを意味します:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

そしてこれは魚で:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

一般的なアドバイスとして、引用することは決して痛くない。

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