在控制台中指示工作进度的最简单方法是什么?输出百分比就足够了,不需要进度条。
仅使用print
会生成很多行,我只想在终端中输入一个字符串。
答案 0 :(得分:23)
最简单的方法是执行wget和其他程序的操作:在进度信息之前打印回车符和ANSI擦除行代码,从而将光标返回到行的开头并替换现有文本。例如:
import Control.Monad
import Control.Concurrent
import System.IO
import Text.Printf
putProgress :: String -> IO ()
putProgress s = hPutStr stderr $ "\r\ESC[K" ++ s
drawProgressBar :: Int -> Rational -> String
drawProgressBar width progress =
"[" ++ replicate bars '=' ++ replicate spaces ' ' ++ "]"
where bars = round (progress * fromIntegral width)
spaces = width - bars
drawPercentage :: Rational -> String
drawPercentage progress = printf "%3d%%" (truncate (progress * 100) :: Int)
main :: IO ()
main = do
forM_ [0..10] $ \i -> do
let progress = fromIntegral i / 10
putProgress $ drawProgressBar 40 progress ++ " " ++ drawPercentage progress
threadDelay 250000
putProgress "All done."
hPutChar stderr '\n'
这里的关键是不打印换行符,以便您可以在下一次进度更新时返回到行的开头。
当然,你可以在这里打印出百分比然后放下吧,但是酒吧很酷:)
答案 1 :(得分:3)
如果我想要一些非常快速和肮脏的东西,我倾向于做的只是打印一系列点。每次有“更多”的进展我只是写另一个点(没有换行)。我调整了“有点进步”的尺度,以便在每秒点数的时间尺度上出现点。不是很复杂,但它表明程序正在做一些事情。
如果你真的有一些衡量总体“进展”的程度(我经常不这样做,但这是你提到的百分比所示),那么你可以宣布整个程序为X点,并在每次进行1 / X进度时打印一个。