サポート拡張

サポート拡張

私はそれが中{かっこ拡張で動作することがわかりました。

echo {1..8}

またはコマンドグループから:

{ls;echo hi}

Bashはどう違いますか?

答え1

簡単な理由は、文字が存在するためですspace

ブレーキ拡張は(引用されていない)スペースを処理しません。

リストには{...}(引用されていない)スペースが必要です。

より詳細な答えはシェルがコマンドラインを解析する方法


コマンドラインを解析(理解)する最初のステップは、コマンドラインをさまざまな部分に分割することです。
これらの部分(しばしば単語またはトークンと呼ばれる)は、各メタ文字でコマンドラインを分割して生成されます。リンクから:

  1. コマンドを固定メタ文字セット(SPACE、TAB、NEWLINE、;、(、)、<、>、|、および&)で区切られたトークンに分割します。トークンの種類には、単語、キーワード、I/O リダイレクタ、セミコロンが含まれます。

メタ文字:spacetabenter;,<>|&

分割後の単語は特定の種類を持つことができます(シェルが理解するように)。

  • コマンド事前割り当て:LC=ALL ...
  • 注文するLC=ALL echo
  • 議論LC=ALL echo "hello"
  • リダイレクトLC=ALL echo "hello" >&2

サポート拡張

「中括弧で囲まれた文字列」(スペースまたはメタ文字を除く)が(上記のように)単一の単語である場合にのみ引用しない、これは「ブラケット拡張」の候補です。内部構造のさらなる検査は後で行われる。

したがって、これは「分岐拡張」に適しており、asまたは(bashではzshが異なります)に{ls,-l}なります。ls -lfirst wordargument

$ {ls,-l}            ### executes `ls -l`
$ echo {ls,-l}       ### prints `ls -l`

しかし、これはそうではありません:{ls ,-l}。 Bashは行を分割しspaceて2つの単語に解析し、以下を実行します{ls(パラメータがありません)。,-l}command not found,-l}

 $ {ls ,-l}
 bash: {ls: command not found

あなたの行:{ls;echo hi}「サポート延長」にはなりません。なぜなら二つメタ文字;space

これは3つの部分に分けられます。{ls新しいコマンド:echo hi};新しいコマンドの開始をトリガーする要素を学びます。このコマンドは{ls見つかりません。次のコマンドは以下を印刷しますhi}

$ {ls;echo hi}
bash: {ls: command not found
hi}

別のコマンドの後に配置すると、とにかく新しいコマンドが始まります;

$ echo {ls;echo hi}
{ls
hi}

リスト

「複合コマンド」の1つは「ブランチリスト」(マイワード)です{ list; }
ご覧のとおり、空白と終端として定義されています;。空白が必要で、
どちらも「予約」されているので、;{}性格」。

したがって、単語として認識されるには、メタ文字で囲む必要があります(ほぼ常に:)space

ポイント2で述べたようにリンクページ

  1. 各コマンドの最初のトークンが....、{、または(場合は、コマンドが実際に複合コマンドであることを確認してください)。

あなたの例:{ls;echo hi}リストではありません。

終了者;とスペースが(少なくとも)必要です{。最後の単語は}閉じる単語として定義されます;

ここにリストがあります{ ls;echo hi; }。これも{ ls;echo hi;}(あまり一般的に使用されていませんが効果的です)(助けてくれた@chorobaに感謝します)。

$ { ls;echo hi; }
A-list-of-files
hi

ただし、コマンドの引数(シェルは違いを知っています)でエラーが発生します。

$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'

しかし、シェルが構文解析していると思うことに注意してください。

$ echo { ls;echo hi;
{ ls
hi

答え2

block{はシェルキーワードなので、次の単語とスペースで区切る必要があり、中括弧拡張にスペースを含めることはできません(中括弧拡張スペースが必要な場合はエスケープする必要があります。)echo {\ ,a}{b,c}

コマンドの先頭に中かっこ拡張を使用できます。

{ls,.}  # expands to "ls ."

ただし、拡張前にグループ化されたコマンドの解析が行われるため、それを使用してブロックに拡張することはできません。

echo {'{ ls','.;}'}  # { ls .;}
{'{ ls','.;}'}       # bash: { ls: No such file or directory

答え3

コマンドラインの構文を確認してこれを確認できます。同様に、式では、最初のecho echoエコーはコマンドとして扱われ、2番目のエコーは最初のエコーの引数として扱われるべきです。

{ cmd; }Bashではスペースとセミコロンが必要なので、とても簡単です。ただし、たとえばzshでは必要ありませんが、{}シェルのコンテキストを分析すると、そのコンテンツがどのように処理されるべきかがわかります。

以下を考慮してください。

alias 1..3=date
{ 1..3; }    #in bash
{1..3}       #in zsh

どちらも現在の日付を返しますが、

echo {1..3}

Return、1 2 3シェルは{}コマンドのパラメータを知っているので、echo拡張する必要があります。

答え4

まず、複合括弧は単語自体でなければならず、コマンドラインの最初の単語でなければなりません。

echo { these braces are just words }

第二に、単一の中括弧は特別ではありません(上記のように)。空の中括弧も特別ではありません。

echo {} # just the token {}: familiar from the find command

カンマがないのはそれだけです。

echo {abc} # just {abc}

これが行動が始まるところです。

echo {a,b} # braces disappear, a b results.

{...}したがって、デフォルトでは、中かっこ拡張が機能するには、少なくとも1つのインスタンスと少なくとも1つのカンマを含む単語(スペースのフィールドに分割されていない)が必要です。

これできるちなみに、コマンドラインの最初の単語は次のようになります。

{ls,-l} .   # just "ls -l ."

関連情報