Bashの前の出力を追加する代わりに上書きする


22

bashタイマーの場合、このコードを使用します。

#!/bin/bash
sek=60
echo "60 Seconds Wait!"
echo -n "One Moment please "
while [ $sek -ge 1 ]
do
   echo -n "$sek "  
sleep 1
   sek=$[$sek-1]
done
echo
echo "ready!"

それは私にそのような何かを与えます

One Moment please: 60 59 58 57 56 55 ...

秒の最後の値を最新のものに置き換えて、出力が大きな軌跡を生成せず、ある位置でリアルタイムのような秒のカウントダウンを生成する可能性はありますか?(私の意味を理解してください:))


watchコマンドを使用してこれを行う方法があるかもしれませんが、その方法は正確にはわかりません。
AJMansfield

回答:


14
#!/bin/bash
sek=60
echo "60 Seconds Wait!"
echo -n "One Moment please "
while [ $sek -ge 1 ]
do
   echo -n "$sek" 

sleep 1
   sek=$[$sek-1]
   echo -en "\b\b"
done
echo
echo "ready!"

2
すごい、ありがとう。他の読者へのお知らせ。上記のコードに合わせるには、スペースのためにecho -en "\ b \ b \ b"を使用する必要があります。
NES

1
+1素敵ですが、... 10未満ではメッセージを食べ始めます
...-lepe

1
うん、使用し\rた方が良い。私の答えをご覧ください。
ミケル

3
bashのマニュアルから:The old format $[expression] is deprecated and will be removed in upcoming versions of bash.。代わりにPOSIX $((expression))または((-commandを使用してください。例えばsek=$(( sek - 1 ))または(( sek = sek - 1 ))または(( sek-- ))
ガイラ

17

基本的にaneeshepの答えと同じですが、長さが常に同じかどうかわからないため\r、Backspace(\b)ではなくReturn()を使用し$sek < 10ます。

また、最初にハードコードではなくechoを使用する必要があり$sekます60

最後に、の後のスペースに注意してください...

#!/bin/bash
sek=60
echo "$sek Seconds Wait!"
while [ $sek -ge 1 ]
do
   echo -ne "One Moment please $sek ... \r"
   sleep 1
   sek=$[$sek-1]
done
echo
echo "ready!"

7

bashを使用すると、特殊変数を使用できますSECONDS

#BASH
SECONDS=0;
while sleep .5 && ((SECONDS <= 60)); do 
    printf '\r%s: %2d' "One moment please" "$((60-SECONDS))"
done
printf '\n'

+1良い答えです。さらに、SECONDSについては知りませんでした。
ミケル

それは動作しますが、テスト済みのwhileループ条件として 'sleep .5'を見るのは少し奇妙です。 sleep 1)と同様に、時間のかかるアクションです... SECONDS この変数は、シェルが開始されてからの秒数に展開されます。(したがって、おそらく0に設定しません。.スクリプトの開始時からさらに60秒間テストします。)+1
Peter.O

個人的に正確なcoutntdownを取得する方法に興味があるという理由だけで、私はさらにコメントしています... $ SECONDSをテストしましたが、「0」に設定されているかどうかはまだ依存していますシステムの現在の小数秒..すなわち '0'に設定すると、0.99 ...の時間になる可能性があります(そのままの場合は同じです)。したがって、平均的な最良の可能性は0.5秒以内です。 ..ただのコメント(コメントの目的:)
Peter.O

@ fred.bearまあ、あなたは本当にそれを正確に得ることは決してないでしょう。カウントダウンの進行中に他のプロセスがCPUやIOを占有し始め、以前の精度が損なわれる可能性があります。できることは、少なくとも X時間の量を待機させ、必要に応じて大まかなカウントダウンを与えることです。プログラムに「1分かかります」と表示された場合、1ミリ秒まで正確に1分かかると思いますか?または、1分かかるか、数秒与えるか、数秒かかりますか?
ガイラ

@geirha ...はい、その変動は99%のケースでは重要ではありません。$ SECONDSに気付いたのは素晴らしいことです...私はその限界を見つけたところです... .01秒のスリープに基づいて終了時間を報告するスクリプトのバリエーション(および、前述のように、外部システムの遅延)が、2回目のクリックでのみ印刷されますが、最初の 'second'が印刷が早すぎることを発見しました(ある場合には、最初の.01秒の直後)..それは私のbash学習曲線のすべての部分です...私はあなたの答えが好きです、それで私はそれをより深く見ました。
Peter.O

3

に加えて、\rまたは\bアプローチして、端末全体に行をクリアするように指示する\033[2K 制御文字を使用することができます。これと比較し\bた場合の利点は\b、削除する文字の数と数を一致させる\r必要がないことです。また、新しい行が古い行より短い場合、画面に文字がはみ出しません。 1。

以下は、この質問にそれをどのように適用できるかの例であり、ここは、ブートメッセージに類似した出力を作成する関連アプリケーションの例です。この特定の例では、タイマーは0秒に達すると消え、タイマーラインは「Ready!」に置き換えられます。フレーズ。

#!/bin/bash
sek=60
echo "60 Seconds"

while ((sek--)); do
    printf "One moment please: %d" "$sek"
    sleep 1
    printf "\r%b" "\033[2K"
done
echo "Ready!"

別の選択肢はdialog、コマンドラインで単純なダイアログを作成するためにコマンドを使用することです。ダイアログはタイマーの間画面上に残り、ループで更新されます。また、終了するまでに、タイマーは「準備完了!押して終了」メッセージにシームレスに置き換えられます。

#!/bin/bash
sek=60
echo "60 Seconds"

while ((sek--)); do
    echo "$sek" | dialog --progressbox "Please wait" 10 25
    sleep 1
done
dialog --msgbox "Ready! Press <OK> to finish" 10 25

dialogmacには存在しません:/
リッキー・レヴィ

1

これは私がここを読んだ後に思いついたものであり、もう1つはライナーです:

SEC=101;for i in `seq $SEC -1 1`;do printf "\rNext in: %`expr length $SEC`ds" "$i";sleep 1;done;echo

より読みやすい:

#!/bin/bash
SEC=101

for i in `seq $SEC -1 1`;do
        printf "\rNext in: %`expr length $SEC`ds" "$i";
        sleep 1;
done
echo

SECは正の整数に設定でき、printfが適切なパディングを処理します。Ubuntuおよびcygwinでテスト済み。


1

キャリッジリターンを配置することでそれを達成できます\r

1行のコードで、次のことが可能です。 echo -ne

for i in {60..1}; do echo -ne "One moment please: $i\r" && sleep 1; done

またはと printf

for i in {60..1}; do printf "One moment please: $i\r" && sleep 1; done

-2

カウントダウンタイマー:

MIN=1 && for i in $(seq $(($MIN*60)) -1 1); do echo -n "$i, "; sleep 1; done; echo -e "nnMessage"

「通常の」ストップウォッチは次のとおりです。

START=$( date +%s ); while true; do CURRENT=$( date +%s ) ; echo $(( CURRENT-START )) ; sleep 1 ; echo -n  ; done

control + cで停止


これは、テキストを上書きについての質問に答えていない
ジェレミーカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.