[Unix] Unixのパイプの動きを考える

How do Unix pipes work?を読みました。

$ cat hogehoge.txt | head -n 2

上記を実行した時にhogehoge.txtが大きなファイルでも2行出力した途端に停止します。
cat hogehoge.txtだけした時には時間がかかるのに、pipeで繋いだ時には一瞬で終わるのはどうしてか?
Unixのpipeは後ろの処理が終了した時にSIGPIPEシグナルで前のプロセスが停止するそうです。
記事の中ではpythonとgoでcatを作成してSIGPIPEを受けて停止するように作成する例が出ていました。
RubyやSwiftではどうやってやるのでしょうか。

Rubyの場合

1
2
3
4
5
#! ruby -Ku
 
while gets
  puts $_
end

SIGPIPEをよしなに処理してくれるようです。

Swiftの場合

Swiftの場合は、ファイルから順に読み込んで処理するメソッドがなかったので、StreamReaderを作成する必要がありました。
StreamReaderを作成すれば以下のように処理できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
import Foundation
 
for argument in CommandLine.arguments {
  if let streamReader = StreamReader(path: argument) {
    defer {
      streamReader.close()
    }
 
    while let line = streamReader.nextLine() {
      print(line)
    }
  }
}

sourceはこちら

rubyはコマンドラインツールを作成するのがしやすいと思いました。

参考URL

0 件のコメント :

コメントを投稿