Вчера я написал небольшое упражнение для моих учеников: сделайте обратную эхо-программу.
Чтобы узнать что-то новое, я попытался реализовать решение Haskell. Тривиальный main = forever $ interact reverse
не работает. Я прошел этот вопрос и произвел исправленную версию:
import Control.Monad
import System.IO
main = forever $ interact revLines
revLines = unlines . map (reverse) . lines
Но эта исправленная версия также не работает. Я прочитал буферную документацию и играл с различными настройками.
Если я устанавливаю 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, связанной с буферизацией?
- Нужно ли вручную настраивать буферизацию, если я хочу написать рабочую программу с использованием обоих методов?
Изменить: Спасибо всем за полезные ответы.
Я принимаю ответ, который дал пламя, он дает мне подсказку с исатти (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