2015-12-19 76 views
1

在命令行上獲得的進度條的常用方法是使用回車符,它會覆蓋前行,在這個腳本看到:命令行的進度條

#!/bin/bash 
echo -ne '[# ] 25%\r' 
sleep 1 
echo -ne '[## ] 50%\r' 
sleep 1 
echo -ne '[### ] 75%\r' 
sleep 1 
echo -ne '[####] 100%\r' 

這是好的...如果你只有想要打印一個進度條。但是更復雜的腳本可能希望打印進度條,同時輸出診斷輸出。您希望您的命令行應用程序的緩衝區演變爲如下(分開):

[# ] 25% 
---- 
msg1 
[# ] 25% 
---- 
msg1 
msg2 
[# ] 25% 
---- 
msg1 
msg2 
[## ] 50% 

等而現在,流行的做法失敗:

#!/bin/bash 
echo -ne '[# ] 25%\r' 
echo "msg 1" 
sleep 1 
echo "msg 2" 
echo -ne '[## ] 50%\r' 
echo "msg 3" 
sleep 1 
echo "msg 4" 
echo -ne '[### ] 75%\r' 
sleep 1 
echo -ne '[####] 100%\r' 

輸出

[email protected]:~$ ./test.sh 
msg 1] 25% 
msg 2 
msg 3] 50% 
msg 4 

它會似乎要實現這一點,任何其他時間要打印一條消息,您需要:

  1. 檢查它是否是一個進度條,
  2. 如果是,清除線,打印輸出加上一個換行符,然後重新打印進度條

(或者,你可以使用的ncurses )。不幸的是,這需要所有可能的東西,可以給輸出玩球。

是否有任何模塊化的方法使這種進度條工作,這不需要將所有其他輸出方法輸出到終端?

回答

3

更新: 您可以使用ANSI/VT100轉義碼/序列執行此操作。

之前我添加了一個工作示例,您需要注意以下事項:

  • 你需要確保你輸出到一個TTY /控制檯。

  • 您需要了解IO(stdout/stderr) 行和TTY行之間的差異。 \r會讓您到達IO行的開頭,即使該行跨越多個TTY行。

  • 這些代碼/序列本機不支持在Windows控制檯中。但是,您可以在ConEmu(推薦)或ansicon中使用它們。


這裏是一個工作示例。代碼應該是不言自明:

#!/bin/bash 

ERASE_SCREEN_AFTER="\033[0J" 
ERASE_LINE_BEFORE="\033[1K" 
ERASE_LINE_AFTER="\033[0K" 
UP="\033[1A" 

up_count=2 
messages="\n" 
progress="" 

echo_repeat() { 
    c="$2" 
    while ((c)); do 
    echo -en "$1" 
    ((c--)) 
    done 
} 

update_status() { 
    echo_repeat "$UP" "$up_count" 
    echo -en "$ERASE_LINE_BEFORE" "$ERASE_SCREEN_AFTER" "\r" 
    echo -en "$messages" 
    echo "$progress" 
} 

add_msg() { 
    messages+="[email protected]\n" 
    update_status 
    ((up_count++)) 
} 

set_progress() { 
    progress="[email protected]" 
    update_status 
} 

echo_repeat "\n" $up_count 

set_progress '[# ] 25%' 
add_msg "msg 1" 
sleep 1 

add_msg "msg 2" 
set_progress '[## ] 50%' 
add_msg "msg 3" 
sleep 1 

add_msg "msg 4" 
set_progress '[### ] 75%' 
sleep 1 

set_progress '[####] 100%' 

你可以做那些代碼/單獨序列得多,無需使用 (n)的詛咒。這包括設置前景/背景顏色,使用粗體字體等功能。

saldl是CLI程序的一個例子,其中廣泛使用了這些代碼/序列。


老答案(過時):如果我正確理解你的問題,所有你需要做的是msg行前添加一個\n

+0

在消息前添加換行符意味着進度消息永遠不會被擦除;我想要刪除舊的進度消息。 –

+0

所以你想要2更新行。一個用於進步,另一個用於消息? –

+0

不是兩條更新行;消息可以單調遞增。我很高興地認爲,只會有一條進展路線。 –