経過時間をbashで表示するプログレスバーを実装したいと思います。そのためには、画面に表示されている最後の行を消去する必要があります(「clear」コマンドはすべての画面を消去しますが、進行状況バーの行のみを消去し、新しい情報に置き換える必要があります)。
最終結果は次のようになります。
$ Elapsed time 5 seconds
次に、10秒後に(画面の同じ位置にある)この文を次のように置き換えます。
$ Elapsed time 15 seconds
\ rでキャリッジリターンをエコーします
seq 1 1000000 | while read i; do echo -en "\r$i"; done
マンエコーから:
-n do not output the trailing newline
-e enable interpretation of backslash escapes
\r carriage return
キャリッジリターン自体は、カーソルを行の先頭に移動するだけです。出力の各新しい行が前の行と少なくとも同じ長さであれば問題ありませんが、新しい行が短い場合、前の行は完全には上書きされません、例えば:
$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789"
0123456789klmnopqrstuvwxyz
新しいテキストの行を実際にクリアするには、\033[K
後に \r
:
$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789"
0123456789
Derek Veitの答えは、行の長さが端末の幅を超えない限りうまく機能します。そうでない場合、次のコードはジャンク出力を防ぎます。
行が初めて書かれる前に、する
tput sc
現在のカーソル位置を保存します。行を印刷したいときはいつでも
tput rc
tput ed
echo "your stuff here"
最初に保存されたカーソル位置に戻り、次にカーソルから下に画面をクリアし、最後に出力を書き込みます。
\ 033メソッドはうまくいきませんでした。\rメソッドは機能しますが、実際には何も消去されず、カーソルを行の先頭に置くだけです。したがって、新しい文字列が古い文字列よりも短い場合、行の最後に残ったテキストを見ることができます。最後に、tputが最善の方法でした。カーソル以外の用途があり、多くのLinuxおよびBSDディストリビューションにプリインストールされているため、ほとんどのbashユーザーが利用できます。
#/bin/bash
tput sc # save cursor
printf "Something that I made up for this string"
sleep 1
tput rc;tput el # rc = restore cursor, el = erase to end of line
printf "Another message for testing"
sleep 1
tput rc;tput el
printf "Yet another one"
sleep 1
tput rc;tput el
プレイする小さなカウントダウンスクリプトを次に示します。
#!/bin/bash
timeout () {
tput sc
time=$1; while [ $time -ge 0 ]; do
tput rc; tput el
printf "$2" $time
((time--))
sleep 1
done
tput rc; tput ed;
}
timeout 10 "Self-destructing in %s"
進行状況の出力が複数行の場合、またはスクリプトがすでに改行文字を出力している場合、次のような行をジャンプできます。
printf "\033[5A"
これにより、カーソルが5行上にジャンプします。その後、必要なものを上書きできます。
それでもうまくいかない場合は、printf "\e[5A"
または echo -e "\033[5A"
、これは同じ効果があります。
基本的に、 エスケープシーケンス を使用すると、画面内のほとんどすべてを制御できます。
復帰文字を使用します。
echo -e "Foo\rBar" # Will print "Bar"
キャリッジリターン\r
。
printf
を含む1行のコード
for i in {10..1}; do printf "Counting down: $i\r" && sleep 1; done
またはecho -ne
for i in {10..1}; do echo -ne "Counting down: $i\r" && sleep 1; done