ほとんどの人が知っているように、シェルを使用すると、コマンドを実行するときに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
)などにすることができます。
明らかに、「複合コマンド」もリダイレクトできます。複合コマンドは、中かっこグループ、サブシェル、または、、、、またはステートメント{ ...; }
内のパイプ(単一の単純なコマンドでもよい)です。( ... )
if
while
for
until
case
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)