3

次のコードを書きました

var=0
cat $file | while read line do
    var=$line
done
echo $var

私が理解しているように、パイプ(|)によってサブシェルが作成されるため、1行目の変数varは最後の行で同じ値になります。

ただし、これで解決します:

var=0
while read line do
    var=$line
done < $file
echo $line

私の質問は、リダイレクトによってサブシェルが作成されないのはなぜですか、または必要に応じて、パイプによってサブシェルが作成されるのはなぜですか?

ありがとう

4

2 に答える 2

13

このcatコマンドは、独自のプロセスが必要で、独自の STDIN と STDOUT があることを意味するコマンドです。基本的に、コマンドによって生成された STDOUT を取得し、catそれを while ループのプロセスにリダイレクトしています。

リダイレクトを使用する場合、別のプロセスを使用していません。代わりに、while ループの STDIN をコンソールからファイルの行にリダイレクトするだけです。

言うまでもなく、2 番目の方法の方が効率的です。昔のUsenetの時代、小さなウィッパースナッパーがインターネットを手に入れ (_やあ、子供たち! 私のインターネットから離れろ!)、派手なグラフィックスとそれらすべての Web ページでインターネットを破壊する前に、何人かの人々は役に立たない使用comp.unix.shellグループに貢献し、偽のcatコマンドを使用した人々に対するCatcat賞。

コードでa を使用している場合はcat、おそらく必要ありません。このcatコマンドは concatenate に由来し、ファイルを連結するためだけに使用されると想定されています。たとえば、以前は 800K フロッピーでSneakerNetを使用していた場合、長いファイルを Unix のsplitコマンドで分割してから、 を使用catしてそれらを再びマージする必要がありました。

于 2011-06-27T21:18:36.500 に答える
2

あるプログラムの stdout を stdin または別のプログラムにフックするためのパイプがあります。2 つのプロセス、場合によっては 2 つのシェル。リダイレクト (>および<) を実行すると、stdin (または stdout) をファイルに再マッピングするだけです。ファイルの読み取り/書き込みは、別のプロセスやシェルなしで実行できます。

于 2011-06-27T21:01:54.313 に答える