昨日私は生徒のために少しxinetdのエクササイズを書いた:逆エコープログラムを作る。Haskellのデフォルトioバッファリング
新しいことを学ぶために、私はHaskellソリューションを実装しようとしました。簡単なmain = forever $ interact reverse
は機能しません。私はthis questionを経て、修正版作っ:
import Control.Monad
import System.IO
main = forever $ interact revLines
revLines = unlines . map (reverse) . lines
をしかし、この修正版も動作しません。私はbuffering documentationを読んで、さまざまな設定で遊んだ。 NoBuffering
またはLineBuffering
と設定すると、プログラムが正常に動作します。最後に、私はxinetdの(echo "test" | nc localhost 7
)から私のプログラムを実行する場合、私はBlockBuffering Nothing
を持って
import System.IO
main = do
hGetBuffering stdin >>= print
hGetBuffering stdout >>= print
標準入出力のデフォルトのバッファリングモードをプリントアウトしますが、CLIから、私は
- 何ですか
LineBuffering
を持っていますxinetd tcpサービスとcliプログラムとの違いは、バッファリングに関するものですか? - 両方の実行方法で動作中のプログラムを書きたい場合、手動でバッファリングを設定する必要がありますか?
編集:は役に立ち解答ありがとうございました。
私はblazeによって与えられた答えを受け入れ、彼は私にisatty(3)のヒントを与えます。 System.IOのドキュメントをもう一度読み、hIsTerminalDevice関数を見つけました。ハンドルの接続を確認できました。
{-# OPTIONS_GHC -W #-}
import System.IO
main = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering
interact revLines
revLines = unlines . map (reverse) . lines
ここでは「永遠」は必要ありません。怠惰のために、 '対話'は入力を待っていて、 'stdin'からの完全な行ごとに、その逆が即座に出力されます。 – tempestadept
私はそれがOS特有だと思っていますが、一般的には、あなたがライン指向のプログラムを持っていれば、おそらく 'LineBuffering'から最良の動作を得るでしょう。 –
私は悪い質問について多くの不平を言うので、私はちょうどあなたを称賛したいと思います。これは大きな問題です。最小限のコード、問題を再現するための明確な指示、独自の進歩を示した明確な証拠、進歩のために知る必要があることの明確な説明。楽しい。 –