2012-01-21 18 views
10

में सरल प्रगति संकेत कंसोल में कार्य प्रगति को इंगित करने का सबसे आसान तरीका क्या है? प्रतिशत को आउटपुट करना पर्याप्त होगा, प्रगति पट्टी आवश्यक नहीं है।कंसोल

केवल print का उपयोग करके बहुत सारी लाइनें तैयार होंगी, मुझे टर्मिनल में केवल एक ही बदलती स्ट्रिंग चाहिए।

+0

'cls' को फिर से निकालने की अनुमति है? –

+0

भी, आप केवल 'echo' के कुछ रूपों का उपयोग कर सकते हैं जो लाइन ब्रेक प्रिंट नहीं करता है, इस प्रकार एक' बैक एक प्रतीक मिट 'नियंत्रण चरित्र था, इसलिए आप एक रोटेटर एनीमेशन (-/| \ से बना) –

+1

बना सकते हैं माई हास्केल कम से कम कहने के लिए जंगली है, लेकिन अगर मुझे सही याद है, तो अंत में \ r के साथ putStr का उपयोग करके एक लाइन फीड के बिना कैरिज रिटर्न होगा जो आपको उस लाइन को ओवरराइट करने देगी जो आपको है। –

उत्तर

21

सबसे आसान तरीका यह होगा कि 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' 

कुंजी यहाँ बात है, के लिए नहीं प्रिंट एक नई पंक्ति है, ताकि आप अगले प्रगति अद्यतन पर लाइन की शुरुआत पर लौट सकते हैं।

बेशक

, तो आप सिर्फ बाहर प्रतिशत यहां प्रिंट और बार छोड़ सकता है, लेकिन एक बार कूलर है :)

+7

'stdout' के बजाय' stderr' पर प्रिंट करना एक अच्छा विचार हो सकता है। आप स्वचालित फ्लशिंग प्राप्त करते हैं, और प्रगति पट्टी को खराब किए बिना इस प्रोग्राम को पाइप में उपयोग करना संभव है। – dflemstr

+0

@dflemstr: अच्छा बिंदु! मैंने कोड को एक सरल समाधान के साथ अद्यतन किया है जो stderr को प्रिंट करता है। – ehird

3

मैं वास्तव में त्वरित और गंदी कुछ चाहते हैं, मुझे क्या करना सिर्फ एक दृश्य मुद्रित किया जाता है होते हैं बिंदुओं का। हर बार "थोड़ा और" प्रगति हुई है, मैं बस एक और बिंदु लिखता हूं (बिना किसी नई लाइन के)। मैं "थोड़ी प्रगति" के उपाय को ट्यून करता हूं ताकि डॉट्स प्रति सेकंड एक डॉट के समय के पैमाने पर आ सकें। बहुत परिष्कृत नहीं है, लेकिन यह दिखाता है कि कार्यक्रम कुछ कर रहा है।

यदि आपके पास वास्तव में कुछ प्रकार की माप है कि कुल "प्रगति" कितनी होगी (मैं अक्सर नहीं करता हूं, लेकिन यह प्रतिशत के आपके उल्लेख से सुझाव दिया जाता है), तो आप बस पूरे कार्यक्रम को घोषित कर सकते हैं एक्स डॉट्स, और प्रत्येक बार जब आप 1/एक्स प्रगति करते हैं तो प्रिंट करें।