Ubuntuの名前付きパイプから一度にn行を読む

Ubuntuの名前付きパイプから一度にn行を読む

Ubuntuで名前付きパイプを試してみましたが、以前に使ったことはありません。私は次のことをしました。

mkfifo pipe
ls>pipe&
cat pipe

これにより、マイフォルダにあるすべてのファイルのリストがpipe表示されます。一度にパイプの2行を読み取ろうとします。だから、一度実行すると、フォルダの最初のファイルと2番目のファイルの名前を提供するコマンドが必要です。コマンドを再実行すると、3番目と4番目のファイル名が必要です。これを行う方法はありますか?

私は努力したhead -2 pipe。最初の2つのファイル名が表示されます。しかし、もう一度実行すると停止します。前進する正しい方法は何ですか?

答え1

読み取り側でFIFOを開いたままにしたい。 1つの方法は、bashに開かれたファイル記述子を保持させることです。

 #!/bin/bash
 mkfifo pipe
 ls > pipe &
 exec 8< pipe
 r2(){
   read -ru 8 fn1
   read -ru 8 fn2
   echo "$fn1" "$fn2"
 }
 r2 # print out first 2 files
 sleep 1 # do something
 r2 # print out next 2 files.

答え2

2行だけを読み込み、もう読み取らないコマンドが必要です。

入力がパイプでないときにこれを行う機能閲覧可能、コマンドには3つのオプションがあります。

  1. 2 番目の改行文字が見つかるまで一度に 1 バイトずつ読みます。
  2. パイプの内容を(使用せずに)見て、2番目の改行文字がどこにあるかを確認し、一度にできるだけ多くのデータを読み取ります。
  3. ブロックの入力を読みます。ただし、2行以上を読んだ場合は、余分な部分をパイプに戻してください。

read()1はバイトごとに1つのシステムコールしかないため、多くのシステムで高価です。 2 と 3 は、すべてのシステムでパイプを調査したり、パイプにデータを書き戻すことをサポートしていないため、すべてのシステムで動作するわけではなく、複数のプロセスが同時にパイプから読み取ると信頼できません。

したがって、一般的に言えば、いくつかの例外を除いて、コマンドは読み取りに干渉しません。正確に入力内容を検索できない場合は、行数を知らせます。

ほとんどの実装では、入力の最初の2行をhead出力しますが、より多くの入力を消費できます。head -n2注目すべき例外の1つは、headksh93シェルの組み込み関数で、可能であることを確認して一度に1バイトずつ読み込む機能です。

一部のコマンドは、処理する最後の行以上を読み取らないように指示できます。

GNUの場合、sedオプションは次のとおりです-u

sed -u 2q

2行(一度に1バイト)を読むと、それがすべてです。

このlineユーティリティ(標準のユーティリティではなく、現在は常に見つかりません)は、1行だけを読むユーティリティです。

内蔵機能は1行以上を読み取ることがread できません。shしたがって、line上記のコマンドは次の方法で実装できます。

IFS= read -r line; printf '%s\n' "$line"

(入力行が終わらなくても改行を追加することに注意してください)。

(POSIXはlineによって達成することができるので実際に削除を正当化しますread)。

line追加の改行を追加せずにeofからfalseを返す実装の場合。

line() {
  if IFS= read -r line; then
    printf '%s\n' "$line"
  else
    printf %s "$line"
    false
  fi
}

そしてtwolinesちょうど:

twolines() { line && line; }

これにより、次のことができます。

mkfifo pipe
ls > pipe &
while
  echo next two lines:
  twolines
do
  continue
done < pipe

関連情報