zsh I / Oリダイレクト:リダイレクトしてからパイプします。何が起こっている?


8

誰かがこのコマンドで何が起こっているのか説明できますか?

echo foo >&2 | grep foo

Zsh(5.0.2)はfoo2回印刷します。これらのコマンドを実行してから、1つはstdoutに、もう1つはstderrに見えます。

{ echo foo >&2 | grep foo } >/dev/null

そして:

{ echo foo >&2 | grep foo } 2>/dev/null

どちらもfoo一度だけ印刷します。

回答:


5

これがMULTIOSの効果です。

echo foo >&2 | grep foo

foostderrに書き込み、さらににパイプfoogrepます。stderrのデフォルトはterminalであるため、2つのfoo行が表示されます。1 つはからecho、もう1つはgrep結果からです。

{ echo foo >&2 | grep foo } >/dev/null

ここでは、stdoutがにリダイレクトされたために1行表示され/dev/nullましたfooが、からの行しか表示されていませんecho

{ echo foo >&2 | grep foo } 2>/dev/null

ここでは、stderrがにリダイレクトされたために1行表示され/dev/nullましたfooが、からの行しか表示されていませんgrep

端末の違いはライン出力色で簡単に確認できます。grep一致したパターンを強調表示します(またはを使用して強制することもできます--color=always)。


MULTIOSnomultiosオプションが設定解除されてデフォルトで有効になりました:

$ unsetopt | grep nomultios
nomultios

それを無効にするには、nomultiosオプションを設定するだけです:

$ setopt nomultios

ああ、zshがそれを実行できることを知りませんでした!私は(基本的に)リダイレクションを理解{echo foo >&2} | grep fooしています。私が言っていることがわかると、コマンドがと同等ではなかった理由を知りたかったのです。上記で質問したコマンドは、stdoutをstderrにリダイレクトし、空のstdoutをgrepにパイプ処理すると考えていました。
Zorawar 2015年

@Zorawar:その質問はあなたの投稿で扱われなかったので、ここで答えます。では{echo foo >&2} | grep foo{echo foo >&2}コマンドと見なされ、サブシェルで実行されました。あなたはそれがA | grep fooどこにAあるかのように考えることができます{echo foo >&2}。この場合、>&2および|分離し、MULTIOSここでは効果がありません。
cuonglm 2015年

@Zorawarこの場合、私はmultiosをオフにしてしまいました。それはかわいいアイデアですが、実際には私はそれがしばしば迷惑で、めったに役に立たないことに気付きました。
Gilles「SO-邪悪なことをやめなさい」2015

@cuonglm、ここで別の質問がありますが、回答がありませんでした。あなたがそれを知っていて、時間があれば、手伝っていただけませんか?
Liu Sha
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.