सबसे आसान तरीका यह होगा कि wget और अन्य प्रोग्राम क्या करते हैं: प्रगति की जानकारी से पहले एक कैरिज रिटर्न और एक एएनएसआई मिट-लाइन कोड प्रिंट करना, इस प्रकार कर्सर को लाइन की शुरुआत में वापस करना और मौजूदा टेक्स्ट को बदलना । उदाहरण के लिए:
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'
कुंजी यहाँ बात है, के लिए नहीं प्रिंट एक नई पंक्ति है, ताकि आप अगले प्रगति अद्यतन पर लाइन की शुरुआत पर लौट सकते हैं।
बेशक
, तो आप सिर्फ बाहर प्रतिशत यहां प्रिंट और बार छोड़ सकता है, लेकिन एक बार कूलर है :)
'cls' को फिर से निकालने की अनुमति है? –
भी, आप केवल 'echo' के कुछ रूपों का उपयोग कर सकते हैं जो लाइन ब्रेक प्रिंट नहीं करता है, इस प्रकार एक' बैक एक प्रतीक मिट 'नियंत्रण चरित्र था, इसलिए आप एक रोटेटर एनीमेशन (-/| \ से बना) –
बना सकते हैं माई हास्केल कम से कम कहने के लिए जंगली है, लेकिन अगर मुझे सही याद है, तो अंत में \ r के साथ putStr का उपयोग करके एक लाइन फीड के बिना कैरिज रिटर्न होगा जो आपको उस लाइन को ओवरराइट करने देगी जो आपको है। –