私はそれが中{
かっこ拡張で動作することがわかりました。
echo {1..8}
またはコマンドグループから:
{ls;echo hi}
Bashはどう違いますか?
答え1
簡単な理由は、文字が存在するためですspace。
ブレーキ拡張は(引用されていない)スペースを処理しません。
リストには{...}
(引用されていない)スペースが必要です。
より詳細な答えはシェルがコマンドラインを解析する方法。
コマンドラインを解析(理解)する最初のステップは、コマンドラインをさまざまな部分に分割することです。
これらの部分(しばしば単語またはトークンと呼ばれる)は、各メタ文字でコマンドラインを分割して生成されます。リンクから:
- コマンドを固定メタ文字セット(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 -l
first word
argument
$ {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で述べたようにリンクページ
- 各コマンドの最初のトークンが....、{、または(場合は、コマンドが実際に複合コマンドであることを確認してください)。
あなたの例:{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 ."