4

これは、bash coproc と残りの coproc 出力のフォローアップです。

一度に1行ずつファイルを処理するために最終的に落ち着いたイディオムは次のとおりです。

coproc cat auto/etc/build.cfg
while read -u ${COPROC[0]} BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
do
    ... commands ...
done

cat入力リダイレクトを使用できるという単純なケースを知っています。これは単純化されたバージョンで、実際のバージョンでは egrep を使用して行のサブセットを選択します。

残念ながら、これは機能しません。

$ cat test.sh
coproc cat auto/etc/build.cfg
while read -u ${COPROC[0]} BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
do
    echo hello
done

$ bash -x test.sh
+ read -u 63 BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
+ cat auto/etc/build.cfg
+ echo hello
hello
+ read -u BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
test.sh: line 2: read: BRANCH: invalid file descriptor specification

ファイルには 4 行ありますが、2 回目の繰り返しまでに、コプロセスはそのファイル記述子とともに消滅し、${COPROC[*]}変数は設定解除されているようです (2 回目の読み取りで fd が欠落していることに注意してください)。

問題を複雑にするために、私は Cygwin と Linux (Fedora) の両方で作業していますが、これは 2 つの環境でわずかに異なる動作を示します。Linux では、上記の動作が得られます。Cygwin では、一部のコマンド (つまりecho、bash 組み込みコマンド) ではこの問題は発生しません。どちらの環境でも、外部コマンドを実行すると、コプロセスが強制終了され、その記述子が破棄されます。

ここでの本当の質問は次のとおりだと思います。

bashで、どうすれば達成できますか

while read (list of vars) from file
do
    one or more commands
done

構成ファイルは短いので、ファイル全体を配列にロードする必要がある場合でも機能します。

これがbashで非常に難しいことに本当に驚いています。

4

2 に答える 2

5

の使用法が機能しない理由がわかりませcoprocん。あなたの例は、Mac OS X のbash 4.2.8 で動作します。ここでは、特定のバージョンのbashにバグがある可能性があります。

コプロセスを使用する代わりに、プロセス置換からリダイレクトできるようです。

while read foo bar baz quux; do
    : use foo, bar, baz, quux in various commands
done < <(commands | that | generate --your lines-to-read)

これは、単純なリダイレクトを使用できる単純なファイルに入力がまだない場合に便利です。


に固執したい場合coprocは、別の定式化を使用できる場合があります。

coproc { commands | that | generate --your lines-to-read ; }
while read foo bar baz quux; do
    : use foo, bar, baz, quux in various commands
done <&${COPROC[0]}
于 2011-10-07T15:10:06.557 に答える
2

この構文の 1 つを次に示します。

while read var1 var2 ... ; do
   # one or more commands
done < file
于 2011-10-07T01:27:08.727 に答える