GNU は特定のシェルに対して {} を見つけてブロックします。どのシェルですか?

GNU は特定のシェルに対して {} を見つけてブロックします。どのシェルですか?

GNU findのマニュアルページには、次の内容が記載されています。

-exec command ;
    [...] The  string `{}'  is  replaced  by the current 
    file name being processed everywhere it occurs in the 
    arguments to the command, not just in arguments where 
    it is alone, as in some  versions  of  find.
    Both  of  these  constructions might need to be escaped 
    (with a `\') or quoted to protect them from expansion 
    by the shell. 

これは(GNU findutils)4.4.2のmanの投稿ですfind

これでb​​ashとdashでこれをテストしましたが、両方を{}ブロックする必要はありません。簡単なテストは次のとおりです。

find /etc -name "hosts" -exec md5sum {} \; 

キャリブレーターをカバーするために必要なカバーがありますか?見つかったファイルに空白(bashから呼び出される)が含まれているかどうかに依存しません。

find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \; 
/home/stefan/Ubuntu One

見つかったファイルがサブシェルに渡されると、状況は異なります。

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \; 
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory

この問題は次の方法で解決できます。

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;

比較してみると:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \; 
/home/stefan/Ubuntu One

しかし、マニュアルページではそのような内容を扱いません。そうですか?それでは、どのシェルが{}これを別の方法で処理しますか?

ベストアンサー1

一般化する: 拡張可能なシェルがあれば、{}今は本当に古いレガシーです。

BourneシェルとPOSIX互換シェルでは、中かっこ(および{}は一般的な文字です(ワイルドカード文字、andなどの(単語)区切り記号、andとは異なります)。次の文字列はすべて文字通り印刷する必要があります。;&[]

$ echo { } {} {foo,bar} {1..3}
{ } {} {foo,bar} {1..3}

1つの中括弧で構成される単語は次のとおりです。予約語、コマンドの最初の単語の場合にのみ特別です。

Ksh は、Bourne シェルの互換性のない拡張で中括弧拡張を実装します。をオフにしてこれを行うことができますset +B。 Bashはこの点でkshを模倣します。 Zsh は中括弧拡張も実装しています。set +Iまたはにsetopt ignore_bracesドラッグできますemulate sh。これらのシェルは、引数で一般的に使用されているように、{}単語の部分文字列(たとえば)でも、いずれにしても拡張されません。foo{}barfindそしてxargs

シングルUnix v2気づく

いくつかの歴史的システムでは、中括弧は制御演算子と見なされます。将来の標準化アクティビティをサポートするには、移植可能なアプリケーションでは、文字自体を表すために引用符で囲まれていない中括弧を使用しないでください。 ISO/IEC 9945-2:1993 規格の今後のバージョンでは、これを要求する可能性があり、{トークンは頻繁に使用される構成により特別なケースが免除される可能性がありますが、}制御演算子として別々に処理することができます。{}find {}

このメモは、この標準の後続のバージョンから削除されました。の例find{}次のように引用されていない目的があります。の例xargs{}歴史的なBourneシェルを参照する必要があるかもしれませんが、今は非常に古いレガシーシステムです。

私が持っているcshの実装(OpenBSD 4.7、Debian の BSD csh、tcsh)すべてが拡張され{foo}ましたが無視されfooました{}

おすすめ記事