パイプの後にコマンドのグループ化が続くと、具体的に何が起こるのでしょうか?

パイプの後にコマンドのグループ化が続くと、具体的に何が起こるのでしょうか?

次のような表現を見たのですcommand1 | {command2;command3;command4}が、これが実際に何を意味するのか考えていました。パイプ記号は知っていますし、{...}中括弧内のコマンドをメイン シェルで強制的に実行することも知っていますが、これらを組み合わせた場合に何を意味するのかわかりません。

答え1

パイプラインの各部分がどれほど複雑であるかは実際には問題ではなく、必要に応じてそれらを個別のスクリプトとして視覚化できる場合がよくあります (特に、bashパイプラインの各部分をいずれにしてもサブシェルで実行する which のようなシェルの場合)。

スクリプト

command2
command3
command4

... どれのだいたい(コマンドがサブシェルで実行されないことを考慮せずに)翻訳すると、実行からの入力が与えられます{ command2; command3; command4; }{ ...; }

command1

最初のスクリプトの 3 つのコマンドが何を実行しているかに応じて、そのうちの 1 つまたは複数のコマンドが からの入力を消費しcommand1、そのうちの 1 つまたは複数のコマンドが何らかの出力を生成する場合、その出力はパイプラインの次の部分、ターミナル、またはパイプラインの出力がリダイレクトされる場所に送られます。

答え2

{...}メインシェルで中括弧内のコマンドを実行するように強制します

これは、中括弧が一般的に何をするかについて適切な説明ではありません。中括弧は、サブシェルを作成しない方法でコマンドをグループ化します。言い換えると、中括弧自体はサブシェルを作成しません。中括弧内のコードは、中括弧がない場合と同じシェルで実行されますが、括弧内のコードは常にサブシェルで実行されます (そのため、そのリダイレクト、変数などは、親シェルや他のシェルに影響を与えません)。

中括弧の目的は、構文上は単一のコマンドが期待される場所に複雑なコマンドを記述できるようにすることです。たとえば、command1 | { command2; command3; command4; }(スペースと最後のセミコロンが必要であることに注意してください) では、パイプの右側は です{ command2; command3; command4; }。コマンドは、次に、次に{ command2; command3; command4; }を実行します。これらのコマンドはすべてパイプから入力を受け取ります。(コマンドは連続して実行されるため、は の実行後に残っている入力を取得します。)command2command3command4command3command2

答え3

中括弧を名前のない関数として考えてください。例:

command234 () { command2; command3; command4; }

command1 | command234 

同じ結果が得られます。 物事が複雑になりすぎる場合は、グループに名前を付けることをお勧めします。 テストのためだけにでも。

答え4

の標準出力は、command1標準入力からの読み取りを開始するコマンド ブロックの最初のコマンドに使用されます。ほとんどの場合、これは になりますcommand2

関連情報