Cygwinからパイプにリダイレクトするときに/ dev / stderrが無効であるのはなぜですか?

Cygwinからパイプにリダイレクトするときに/ dev / stderrが無効であるのはなぜですか?

/dev/stderr私は最近最新のcygwinでは動作しませんが、成熟したDebianのインストールにも存在する驚くべき問題を発見しました。 (編集:私の初期の考えとは異なり、私のDebianシステムはこのエラーを公開せずに単に目的の出力を生成します。今はこれがcygwinのバグであると仮定する必要があります。)

背景:私は何千行もの出力を生成するためのツール(特に大規模生産システムのバージョン制御システム)を使用して作業しています。スクリプト制御を介して実行中で、ノイズの多いツール出力をログファイルにリダイレクトするオプションが必要です。簡単な解決策は、常に(stderrとstdout)出力を環境変数に格納されているファイルシステムターゲットにリダイレクトするようです。端末(または一部のユーザー制御宛先)に出力が必要な場合、宛先はDBG_STDERR「/dev/stderr」にすぎず、そうでない場合は一時ファイル名です。一般的なツール実行ラインは次のとおりですnoisy_command >> "$DBG_STDERR" 2>&1

スクリプトの出力をパイプしないとうまくいきます。最小限の表現は次のとおりです。

$ uname -a
CYGWIN_NT-6.1-WOW xxxxxxx 2.8.1(0.312/5/3) 2017-07-03 14:06 i686 Cygwin

$ bash --version
GNU bash, version 4.4.12(3)-release (i686-pc-cygwin)

$ cat say-something.sh
#!/bin/sh
echo something > /dev/stderr

$ (x=$(./say-something.sh 2> /dev/stderr)) 2>&1 |cat
./say-something.sh: line 2: /dev/stderr: No such file or directory

$ (x=$(./say-something.sh 2> /dev/stderr)) 2>&1
something

$ (x=$(./say-something.sh 2> /dev/stderr))  |cat
something

$ x=$(./say-something.sh 2> /dev/stderr) 2>&1 |cat
something

もちろん、すべてのリダイレクトとネストされたシェルはコンテキストに合わないように奇妙に見えます。 say-something.sh は実際には別のスクリプトによって呼び出されるため、追加のシェルが必要です。 fd 2からstderrへの冗長リダイレクトは、ファイル(/dev/stderrまたは実際に設定可能な変数の内容である他のパス)へのオプションのリダイレクトに便利な「スイッチ」です。

失敗した例による実験からわかるように、このパイプラインのすべてのコンポーネントが必要なようです。すべて成功します。

  • 標準出力の最後のパイプが必要です
  • stderrをstdoutにコピーするには、呼び出し元が必要です。
  • コマンド代替シェルが必要です。

ベストアンサー1

/dev/stderr名前はパイプにリダイレクトするときに実際に有効です。不可能かもしれないのは、/dev/stderr最終目標を直接開くことです。以下を見てください。

$ (echo Testing testing > /dev/stderr) |& cat
Testing testing

||&によって生成されるか、一般的にパイプは匿名パイプ;表示された名前ファイルシステムのオブジェクトと一致しません。。たとえば、次のような簡単なことを試してみることができます。

$ ls -la /dev/fd/ |& cat
total 0
dr-x------ 2 alexp alexp  0 Jul  6 18:23 .
dr-xr-xr-x 9 alexp alexp  0 Jul  6 18:23 ..
lrwx------ 1 alexp alexp 64 Jul  6 18:23 0 -> /dev/pts/4
l-wx------ 1 alexp alexp 64 Jul  6 18:23 1 -> pipe:[1058859]
l-wx------ 1 alexp alexp 64 Jul  6 18:23 2 -> pipe:[1058859]
lr-x------ 1 alexp alexp 64 Jul  6 18:23 3 -> /proc/4335/fd

開こうとしている(最終)ターゲットの/dev/stderr名前は非常に/dev/stderr珍しいです。避ける実際の目標を見つけるために努力してください。

おすすめ記事