Gestern habe ich eine kleine xinetd Übung für meine Schüler geschrieben: mache ein Reverse-Echo-Programm.Haskell default io buffering
Um etwas Neues zu lernen, habe ich versucht, eine Haskell-Lösung zu implementieren. Das triviale main = forever $ interact reverse
funktioniert nicht. Ich ging durch this question und machte eine korrigierte Version:
import Control.Monad
import System.IO
main = forever $ interact revLines
revLines = unlines . map (reverse) . lines
Aber diese korrigierte Version auch nicht funktioniert. Ich lese die buffering documentation und spielte mit den verschiedenen Einstellungen. Wenn ich NoBuffering
oder LineBuffering
einstelle, funktioniert mein Programm korrekt. Schließlich gedruckt i die Standardpuffer Modi für stdin und stdout
import System.IO
main = do
hGetBuffering stdin >>= print
hGetBuffering stdout >>= print
ich BlockBuffering Nothing
habe, wenn ich mein Programm von xinetd laufen (echo "test" | nc localhost 7
), aber von cli habe ich LineBuffering
- bekam Was ist der Unterschied zwischen einem xinetd TCP-Dienst und einem CLI-Programm, in Bezug auf die Pufferung?
- Muss ich manuell die Pufferung einstellen, wenn ich ein Arbeitsprogramm mit beiden laufenden Methoden schreiben will?
Edit: Vielen Dank für die hilfreichen Antworten.
Ich akzeptiere die Antwort, die von blaze gegeben wurde, er gibt mir einen Hinweis mit isatty (3). Ich habe nochmal die System.IO Dokumentation durchgelesen und die hIsTerminalDevice Funktion gefunden, mit der ich die Verbindung des Griffes überprüfen kann.
Für das Protokoll, hier ist mein letztes Programm:
{-# OPTIONS_GHC -W #-}
import System.IO
main = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering
interact revLines
revLines = unlines . map (reverse) . lines
Sie brauchen nicht für immer hier. Aufgrund der Faulheit wird "interact" weiterhin auf Eingabe warten, und für jede vollständige Zeile von "stdin" wird die Umkehrung sofort gedruckt. – tempestadept
Ich denke, es ist Betriebssystem-spezifisch, aber im Allgemeinen, wenn Sie ein zeilenorientiertes Programm haben, dann werden Sie wahrscheinlich das beste Verhalten von 'LineBuffering' bekommen. –
Ich beschwere mich oft über schlechte Fragen, also wollte ich dich nur loben. Das ist eine gute Frage. Minimierter Code, klare Anweisungen zum Reproduzieren Ihres Problems, eindeutige Beweise dafür, dass Sie selbst Fortschritte erzielt haben, und eine klare Beschreibung dessen, was Sie wissen müssen, um Fortschritte zu erzielen. Herrlich. –