リダイレクトはコマンドリストとどのようにやり取りするのですか?

リダイレクトはコマンドリストとどのようにやり取りするのですか?

ほとんどの人が知っているように、シェルを使用すると、コマンドを実行するときにstdin / stdout / stderrをリダイレクトし、あるコマンドから別のコマンドに出力をパイプすることもできます。

演算子を使用して条件付きまたは無条件に順番に実行されるコマンドの「リスト」を作成できることを知っている人はほとんどいません; && ||

これらの機能はどのように相互作用しますか?何かをしたら

command1 && command2 >file

最後のコマンドの出力のみをリダイレクトしますか、それとも両方ですか?書くなら

command1 | command2 && command3 | command4

実際には何をしますか?これら2つのパイプに条件がありますか?それともパイプライン含むパイプラインステップの1つである条件は何ですか?

私が知っている限り、シェルは明確にするために括弧を追加することをサポートしていないので、どのように解釈を要求できるのかわかりません。 。 (ほとんどの人のように、私はBashだけを使います。)

答え1

指揮中

command1 && command2 >file

出力はcommand1リダイレクトされませんが、出力は次command2のようになります。

$ echo hello && echo ok >file
hello
$ cat file
ok

リダイレクトはcommand1個別に実行できます。

command1 >file1 && command2 >file2

指揮中

command1 | command2 && command3 | command4

の出力はcommand1にパイプされますcommand2。最初のパイプが終了状態 0 で終了すると、2 番目のパイプも同様の方法で実行されます。

$ echo hello | cat && echo bye | cat
hello
bye

command2 && command3リストをグループ化するには、次のように作成します。

command1 | { command2 && command3; } | command4

これは、出力がcommand1複合コマンドにパイプされることを意味しますcommand2 && command3。その後、複合コマンドの出力が次にパイプされますcommand4

$ echo hello | { read message && printf 'We got "%s"\n' "$message"; } | rev
"olleh" tog eW

単一の単純なコマンド(以下を参照)をリダイレクトできます。

$ echo hello | { read message && printf 'We got "%s"\n' "$message"; echo bye >&2; } | rev
bye
"olleh" tog eW

&&シェル構文では、「完全なコマンド」は、またはで区切られた一連のパイプで構成されています||。これはとても緩い話す。これは、とが&&パイプラインよりも||高い優先順位を持つことを意味します。|

一方、リダイレクトは、構文が「単純なコマンド」構成のリダイレクト部分を作成するため、現在のコマンドと緊密に統合されます。単純なコマンドは、いくつかのコマンドプレフィックス、コマンド名、およびコマンドサフィックス(プレフィックスとサフィックスはオプションです)です。コマンドプレフィックスは、環境変数への割り当て(VAR=value myscript)またはリダイレクト(>outfile cat)です。同様に、コマンドサフィックスはリダイレクト(cat >outfile)などにすることができます。

明らかに、「複合コマンド」もリダイレクトできます。複合コマンドは、中かっこグループ、サブシェル、または、、、、またはステートメント{ ...; }内のパイプ(単一の単純なコマンドでもよい)です。( ... )ifwhileforuntilcase

POSIXシェル(およびbash拡張)の完全な構文は、POSIX標準にあります。以下は、構文規則の最上位レベルです。

program          : linebreak complete_commands linebreak
                 | linebreak
                 ;
complete_commands: complete_commands newline_list complete_command
                 |                                complete_command
                 ;
complete_command : list separator_op
                 | list
                 ;
list             : list separator_op and_or
                 |                   and_or
                 ;
and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline
                 ;
pipeline         :      pipe_sequence
                 | Bang pipe_sequence
                 ;
pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command

(引用する:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02)

関連情報