昨天我爲我的學生寫了一個小小的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
,我的程序可以正常工作。最後我打印出來的stdin和stdout的默認緩衝模式
import System.IO
main = do
hGetBuffering stdin >>= print
hGetBuffering stdout >>= print
我有BlockBuffering Nothing
如果我從運行的xinetd(echo "test" | nc localhost 7
)我的計劃,但是從CLI我有LineBuffering
- 是什麼一個xinetd tcp服務和一個cli程序之間的差異,是否考慮緩衝?
- 如果我想用兩種運行方法編寫一個工作程序,是否必須手動設置緩衝?
編輯:謝謝大家的幫助的答案。
我接受火焰給出的答案,他給我一個提示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
你不需要'永遠'在這裏。由於懶惰,'interact'將繼續等待輸入,並且對於來自'stdin'的每個完整行,它的反向將立即打印。 – tempestadept
我認爲它的操作系統特定,但通常如果你有一個面向行的程序,那麼你可能會從'LineBuffering'中獲得最好的行爲。 –
我做了很多抱怨不好的問題,所以我只想讚揚你。這是一個很好的問題。最小化代碼,明確指示重現您的問題,明確證明您自己取得了一些進展,並清晰地描述了您需要了解的進展情況。愉快。 –