Перезапишите предыдущий вывод в 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 ...

Существует ли возможность заменить последнее значение вторых новым так, чтобы вывод не генерировал большой след, но обратный отсчет секунд как реальное время в одном положении? (Надежда, Вы понимаете то, что я имею в виду :))

22
задан 4 December 2010 в 13:34

7 ответов

#!/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!"
14
ответ дан 23 November 2019 в 01:33

В основном то же как ответ aneeshep, но Возврат использования (\r) а не Клавиша Backspace (\b) потому что мы не знаем, будет ли длина всегда тем же, например, когда $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!"
17
ответ дан 23 November 2019 в 01:33

С ударом можно использовать специальную переменную SECONDS.

#BASH
SECONDS=0;
while sleep .5 && ((SECONDS <= 60)); do 
    printf '\r%s: %2d' "One moment please" "$((60-SECONDS))"
done
printf '\n'
7
ответ дан 23 November 2019 в 01:33

Таймер Countdown:

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 для остановки

-2
ответ дан 23 November 2019 в 01:33

Это - то, что я придумал после чтения здесь и немного больше, один лайнер:

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
ответ дан 23 November 2019 в 01:33

В дополнение к \r или \b подходы, возможно использовать \033[2K управляющий символ, который говорит терминалу очищать целую строку. Преимущество этого по сравнению с \b это, Вы не должны соответствовать количеству \b с количеством символов Вы хотите удалить, и по сравнению с \r не будет символов, терпящих на экране, если новая строка будет короче, чем старая.

Ниже пример того, как он может быть применен к этому вопросу и здесь является примером связанного приложения для создания вывода, подобного сообщениям загрузки. В этом конкретном примере закончится таймер, после того как 0th второй достигнут, и строка таймера будет заменена "Готовым!" фраза.

#!/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
3
ответ дан 23 November 2019 в 01:33

Может достигнуть его путем размещения возврата каретки \r.

В одной строке кода это возможно с 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
1
ответ дан 23 November 2019 в 01:33

Другие вопросы по тегам:

Похожие вопросы: