コマンドとそのオプションへの引数として中括弧{}の使用


11

私は最近{}、開始括弧と終了括弧の間に何もない、括弧のペアをコマンドの引数として、さらにはオプションの引数として使用する例を見つけました。

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

ドキュメントなし

私の問題は、上記の例のようなコンテキストでのの使用法を説明するドキュメントがGNU Bashマニュアルに見つからないこと{}です。

のようにパラメータ展開では、括弧が括弧で囲まれている必要があるため、これはパラメータ展開ではないと思います${}

これはブレース展開にすることもできません。なぜなら、それは{x..y[..incr]}、where の形式をとっており、オプションxyはないからです。

また、は引数として使用されるため、コマンドグループにすることもできません{}

ご質問

  1. 括弧で囲まれたペアは、{}それを受け入れるコマンドの引数として、一般的にどういう意味ですか?

  2. {}引数の使用法を説明したドキュメントはどこにありますか?


一部のコマンドにはこのオプションがあります{}- コマンドを使用targetsすると、ファイルをfind削除/ rm検出します。
Tuyen Pham

回答:


16

これらの中括弧はbashによってそのままにされます。それらはそれぞれfindとに属しxargs、それらのマンページで説明されています。

man find

-exec コマンド ;

コマンドを実行します。0ステータスが返された場合はtrue。次のfindの引数はすべて、からなる引数が見つかるまで、コマンドの引数と見なされます;。文字列{}は、の一部のバージョンのように単独である引数だけでなく、コマンドの引数で発生するすべての場所で処理されている現在のファイル名に置き換えられますfind。これらの構造は両方とも\、シェルによる拡張から保護するために、エスケープ(を使用)または引用符で囲む必要がある場合があります。-execオプションの使用例については、「例」セクションを参照してください。指定された コマンド一致したファイルごとに1回実行されます。コマンドは、開始ディレクトリで実行されます。-exec アクションの使用を取り巻くセキュリティ上の問題は避けられません。-execdir代わりにオプションを使用してください。

-exec コマンド {} +

この-execアクションのバリアントは、選択されたファイルに対して指定されたコマンドを実行しますが、コマンドラインは、選択された各ファイル名を最後に追加することによって構築されます。コマンドの呼び出しの総数は、一致したファイルの数よりもはるかに少なくなります。コマンドラインは、コマンドラインを構築するのとほとんど同じ方法でxargs構築されます。{}コマンド内で許可されるのは1つのインスタンスのみです。コマンドは、開始ディレクトリで実行されます。場合はfind出会いエラーいくつかの保留中のコマンドが全く実行されない場合がありますので、これは時々 、即時終了を引き起こす可能性があります。このバリアントは-exec常にtrueを返します。

-execdir コマンド ;

-execdir コマンド {} +

と同様 -execですが、指定されたコマンドは、一致したファイルを含むサブディレクトリから実行されます。通常は、検索を開始したディレクトリではありません。これは、一致するファイルへのパスの解決中に競合状態を回避するため、コマンドを呼び出すためのはるかに安全な方法です。同じように -exec 行動、 + の形は -execdir 同じサブディレクトリに存在する唯一のリストファイルをより1つのマッチファイルよりもプロセスへのコマンドラインを構築しますが、コマンドの任意の呼び出し。このオプションを使用する場合は、$PATH環境変数が参照しないようにする必要があります.; それ以外の場合、攻撃者は、実行するディレクトリに適切な名前のファイルを残して、任意のコマンドを実行できます-execdir$PATH空のエントリや絶対ディレクトリ名ではないエントリについても同様です。場合はfind出会いエラーいくつかの保留中のコマンドが全く実行されない場合がありますので、これは時々 、即時終了を引き起こす可能性があります。アクションの結果は、+または;バリアントが使用されているかどうかによって異なります。 -execdir commandは {} +常にtrueを返しますが、commandが0を返した場合のみ-execdir command {} ;はtrueを返します。

man xargs

-I replace-str

initial-arguments内のreplace-strの出現箇所を標準入力から読み取られた名前に置き換えます。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字です。意味-x-L 1ます。

-i[ replace-str ]、--replace[ =replace-str ]

replace-strが指定されている場合、このオプションは-Ireplace-strの同義語です。場合置き換える-STR引数が欠落している、効果は同じです。このオプションは非推奨です。代わりに使用してください。-I{}-I

編集:そしてここでなぜ bashはそれらの中括弧を無視するのですか?

man bash

{ リスト; }

list は、現在のシェル環境で単純に実行されます。 リストは改行またはセミコロンで終了する必要があります。これはグループコマンドと呼ばれます。返却ステータスはリストの終了ステータスです。メタ文字 and とは異なり、{および}は予約語であり、予約語の認識が許可されている場所で使用する必要があることに注意してください。これらは単語の区切りを引き起こさないため、空白または別のシェルメタ文字によってリストから分離する必要があります。

強調のために:リストは改行またはセミコロンで終了する必要があります


1
ありがとうございました!私が書いman xargsた人が{}実際に何を意味するのかわからなくても、著者-execがのmanページにあるの説明に読者をリダイレクトしなかった(しゃれた意図はなかった)ことに不愉快ですfind
Niko Gambt

@NikoGambt -私は共感...
ティンク

5
@NikoGambtさて、{}は非推奨の-iのデフォルト値であることを除いて、xargsには何の意味もありません。それ以上にどのような説明が必要かわかりません。あなたが投稿した例では、そうであったかもしれませんxargs -Iab echo ab。それは純粋に恣意的な選択です。
Random832

@ Random832を使用してさらにテストを行った後-I、そのオプションが実際に何を行うかを理解しました。はい、{}あなたが言ったように、恣意的です。説明に戸惑いましたIf the replace-str argument is missing, the effect is the same as -I{}-I引数なしがと同じだった場合-I{}cat foo | xargs -I echo {}を実行した場合と同じ結果になりますcat foo | xargs -I{} echo {}。ただし、同じではありません。前者はエラーであり、私をさらに混乱させたのはエラーメッセージでしたがxargs: {}: No such file or directory、これは実装によるものです。
Niko Gambt

1
@NikoGambt -I(大文字のI)引数なしでは実行できません。への議論は-Iだったecho。これが主な違いである-I-i(非必須の引数とオプションはまれであると混乱するので、および推奨されていません-i理由)
Random832
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.