提问人:string_loginUsername 提问时间:4/8/2023 更新时间:4/9/2023 访问量:61
打印语句未实时执行
Print statements not being executed in real time
问:
我有一个包装器,每当返回非零退出代码时,它都会提前退出,并返回输出readCreateProcessWithExitCode
stdout
import System.Process
runShell :: String -> String -> IO String
runShell cmd msg = do
(ec, r, err) <- readCreateProcessWithExitCode (shell cmd) ""
when (isFailure ec) (error $ msg <> ": " <> err)
return r
从文档页面来看,似乎类似于更简单的,它声称会阻止,直到分叉进程终止。readCreateProcessWithExitCode
readProcess
现在,每当我尝试使用 .stdout
putStrLn
fn :: IO ()
fn = do
void $ runShell "lightweight" "err1"
print "log1"
void $ runShell "expensive" "err2"
print "log2"
假设两个命令执行都成功,并且第二个命令需要几秒钟才能执行,则该函数应在运行后几乎立即记录,等待几秒钟,然后打印 .然而,事实并非如此 - 日志似乎被“暂停”,并且仅在程序执行结束时一次性打印。"log1"
lightweight
"log2"
我以为懒惰的评估与此有关,但明确评估结果也无济于事putStrLn
() <- putStrLn "log1"
答:
3赞
string_loginUsername
4/8/2023
#1
正如 Willem Van Onsem 在评论中指出的那样,默认情况下会进行一些缓冲。可以使用以下方法禁用它stdout
hSetBuffering stdout NoBuffering
评论
0赞
Daniel Wagner
4/15/2023
LineBuffering
在效率和及时性之间可能比 .它是 stdout 的默认值,除非您以不寻常的方式运行程序,例如作为管道的一部分。NoBuffering
评论
hSetBuffering stdout NoBuffering
hFlush stdout
print
putStrLn "..."