2012-01-21 5 views
10

콘솔에서 작업 진행 상태를 나타내는 가장 쉬운 방법은 무엇입니까? 백분율을 출력하면 충분하므로 진행률 표시 줄이 필요하지 않습니다.콘솔의 간단한 진행 표시

단지 print을 사용하면 많은 로트가 생성되므로 터미널에 단 하나의 변경 문자열 만 있으면됩니다.

+0

은 다시 그릴 수있는'cls'입니까? –

+0

또한 줄 바꿈을 인쇄하지 않는 일부 형태의'echo'를 사용할 수 있습니다. 따라서'back one symbol erase' 제어 문자가있어서 로테이터 애니메이션을 만들 수 있습니다 -/| \) –

+1

나의 Haskell은 가장 덜 말할만큼 녹슬지 만, 정확히 기억한다면 끝에있는 putStr을 사용하면 라인 피드를 사용하지 않고 캐리지 리턴을 수행하여 사용자가있는 행을 덮어 쓸 수있게해야합니다. –

답변

21

가장 간단한 방법은 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' 

중요한 것은, 하지 인쇄 개행이다. 물론

, 당신은 여기 비율을 인쇄하고 줄을 삭제하지만, 바 쿨러입니다 수 : 난 그냥 순서를 인쇄되어하는 경향이 무엇

+7

'stdout' 대신'stderr'에 인쇄하는 것이 좋습니다. 자동 플러싱이 발생하며 진행 막대가 엉망이 아닌 파이프에서이 프로그램을 사용할 수 있습니다. – dflemstr

+0

@dflemstr : 좋은 지적입니다! stderr로 출력하는 간단한 솔루션으로 코드를 업데이트했습니다. – ehird

3

뭔가 정말 신속하고 더러운 싶다면, 점의. "조금 더"진행될 때마다 나는 또 다른 점 (줄 바꿈없이)을 씁니다. 나는 "점진적 비트"의 측정을 조정하여 초당 도트의 시간 스케일에 관한 점들이 나옵니다. 별로 정교하지는 않지만 프로그램이 뭔가를하고 있다는 것을 보여줍니다.

"진행률"이 얼마나 될지 측정 할 수있는 척도가 있다면 (나는 자주하지 않지만 백분율에 대한 언급으로 제안합니다), 전체 프로그램을 선언 할 수 있습니다 X 점을 찍고 1/X 진행을 할 때마다 인쇄합니다.