command | getline var
の違いを理解しようとしていますcommand |& getline var
。通常どれを使うべきですか?コプロセスと双方向パイプについて読みましたが、状況が本当に混乱しているので説明が必要です。
実は私が使っているのは
kmd=sprintf("%s%d\n", "tput bold; tput setaf ", knum)
tseq[knam] = ( (kmd | getline outp) > 0 ? outp : "<" knam ">" )
close(kmd)
ここでの共同プロセスは何ですか? tputを使用していますか?コードには一方向パイプ通信しかないと思います。これを使用すると、どのような利点がkmd |& getline outp
あり、後者を使用する必要がありますか?
答え1
あなたの質問のコードには補助プロセスはありません。呼び出すサブシェルを作成してから、tput
そのサブシェルの出力を読み取るだけですgetline
。
情報What would be the benefit of using kmd |& getline outp, and should I use the latter instead?
- 役に立たないだけでなく、これは構文の半分にすぎないため、次のことが必要です(エラー処理を含む)。
print knum |& kcmd
kcmd |& getline outp
close(kcmd)
しかし、これはstdinを読み込み、stdoutを生成するコマンドが含まれている場合にのみ意味があります。kcmd
下痢 そうしても、やりたいことに何の役にも立たず、コードが不要になります。鈍い人。
以下は、コルーチンが有用な場合の例です。パイプを介して着信数値ストリームを並べ替えてから、sort
数字を印刷する前に数字で操作を実行します。
$ cat tst.awk
BEGIN {
cmd = "sort -rn"
}
{ print |& cmd }
END {
close(cmd, "to")
while ( (cmd |& getline line) > 0 ) {
print line, line / NR
}
close(cmd)
}
$ seq 5 | awk -f tst.awk
5 1
4 0.8
3 0.6
2 0.4
1 0.2
デフォルトでは、一時ファイルに書き込む必要があるawkスクリプトを作成する場合は、そのファイルに対して外部コマンドを呼び出してから、そのコマンドの出力をスクリプトに戻します。ここでは、コプロセッシングの使用を検討する必要があります。一時ファイルを作成する必要がないので本当です。
詳細については、Arnold RobbinsのEffective AWKプログラミング5版の本をダウンロードして、他のプロセスとの双方向通信セクションを読んでください。
答え2
いいえ、引き続き単純な「|」を使用する必要があります。あなたの仕事が以下の場合:いくつかのデータを外部ツールに提供し、ツールによって提供される結果を使用してください。これは簡単な一方向パイプで十分です。
双方向パイプは、次の場合にのみ必要です。
- 自分のプロセスが存続している間、外部ツールの同じインスタンスをメモリに保持しようとしています。
- 外部ツールに送信されるデータは論理的にパケットで区切られます。
- 次のパケットを送信する前に、1つのパケットを処理した結果を受け取る必要があります。
- 前のパケットの結果に基づいて、次のパケットを調整する必要があります。
これら4つの質問の1つが「いいえ」の場合、双方向パイプは必要ありません。
双方向パイプを使用する実際のケースを作成することは困難です。おそらく、いくつかのデータベースクエリツールやWebアプリケーションで使用するために発明されたでしょう。ただし、ほとんどの場合、ある種のサーバーを使用する必要がある場合、これらの操作は通常、シェルなどの言語でもperl
解決できますpython
。awk
通常、テキスト処理専用に予約されています。
非現実的ですが、技術的に正しい例は次のとおりです。
#!/bin/gawk
BEGIN {
tool="bc"
print "2+3" |& tool
tool |& getline res
if (res>4)
print "5+6" |& tool
else
print "10+45" |& tool
tool |& getline res
close(tool, "to")
print res
}
ここに示すように、最初の印刷では、「クエリ」を外部ツール(bc
この場合は単純な電卓)に送信します。次に、最初のクエリの結果に基づいて別のクエリを送信し、最後に結果を印刷します。両方のクエリを処理するツールの同じインスタンスです。最初からprint "2+3" |& command
特別声明まで公開されますclose(command, "to")
。