5

連続データストリーム(実際にはパイプ)から1行ずつ読み取る必要があり、1行目以降で終了する必要があります。1行目の直後。とても簡単に聞こえましたが、「head -n 1」を使用して、headが終了する前に実際に2行目を入力する必要があることに気付きました。

テストケース:

[s@svr1 ~]$ cat | head -n 1    
123    <- I type this first (followed by enter, of course)
123    <- I get this output from head, but the command does no exit
456    <- Then I need to type this for the command to exit and bring me back to the prompt
[s@svr1 ~]$

誰かが(何よりもまず)なぜそれがそのように動作しているのか、そしておそらく私が必要なものをどうやって手に入れることができるのかを説明できますか?(そして私は基本的なLinux / Unixの軽量ビルディングブロックに固執したい。Perl、Pythonなどはない...)

ありがとう

4

3 に答える 3

8

を使用しているためcat | head -n 1、これはcat の無駄な使用であり、とは異なりますhead -n 1head -n 1コンソールで実行すると、必要な動作が得られます — 1head行を読み取り、出力して終了します。

cat | head -n 1すると、次のようになります。

  1. cat入力から「123」を読み取ります。
  2. cat出力に「123」を書き込みます。
  3. headcatは、その入力 (の出力に接続されている) から "123" を読み取ります。
  4. head出力に「123」を書き込み、終了します。
  5. cat入力から「456」を読み取ります。
  6. cat出力に「456」を書き込もうとします。
  7. catSIGPIPE出力の反対側のプロセスが終了したため、取得します。
  8. cat終了します。

catは に "123" が書き込まれるとすぐに別の読み取りを開始し、 2行目を書き込むまで が終了しheadたことを認識しません。head

于 2012-11-23T22:29:37.590 に答える
0

でパイプを閉じることができますcontrol-d。次に、出力バッファがフラッシュされ、ヘッドはEOFを取得して、さらに入力を取得する前に終了します。

[s @ svr1〜]$猫| ヘッド -n1123 123
[ s @ svr1〜] $

control-d

head最初の行を読み取った後に停止します。あなたはそれを確認することができます

[s @ svr1〜]$猫| ヘッド-n1

次に、ps aux | grep -w -e cat -e headを実行します。

...猫
...頭
...grep-e cat -e head

次に入力します

123
123

その後、ps aux | grep -w -e cat -e headもう一度実行します。

...猫
...grep-e cat -e head

et voila、頭がなくなった。つまり、頭がぶらぶらしているのではなく、EPIPEを受信した後、2行目を書き込もうとしたときに中止する猫です。

于 2012-11-23T22:13:21.533 に答える
0

誰かが(何よりもまず)なぜそれがそのように振る舞うかを説明できますか?

catファイル名が指定されていない場合に使用STDINします-そのため、2行目または^ Dを指定するのを待っていました.

を使用 sed -n 1p filename して、最初の行のみを取得したり、最初の行sed '1!d' filename以外をすべて削除したりできます。

于 2012-11-23T22:35:25.990 に答える