추가하지 않고 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 Nice, 그러나 ... 10 세 미만은 메시지를 먹기 시작합니다.
lepe

1
그래, 사용하는 것이 좋습니다 \r. 내 대답을 참조하십시오.
Mikel

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-- )).
geirha

17

기본적으로 aneeshep의 답변과 동일하지만 길이가 항상 같은지 여부를 알 수 없기 때문에 \rBackspace ( \b) 대신 Return ( )을 사용합니다 ( 예 : when) $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에 대해 전혀 몰랐습니다.
Mikel

그것은 작동하지만 테스트 된 while-loop 조건으로 'sleep .5'를 보는 것은 조금 이상합니다. 그러나 특히 $ SECONDS의 사용은 실시간과 관련이 있기 때문에 (즉, 사이의 고정 경과 시간이 아니기 때문에) 절전 모드에서와 같이 시간이 많이 걸리는 작업 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 분이 걸리거나 몇 초가 걸리나요?
geirha

@geirha ... 그렇습니다. 99 %의 경우 차이가 중요하지 않으며 $ SECONDS에 대해 알게 되었기 때문에 그 한계를 찾고 있습니다. .01 초의 휴면 (및 외부 시스템 지연)을 기준으로 마무리 시간을보고하지만 1 초만 클릭하면 인쇄되지만 첫 번째 '초'가 너무 빨리 인쇄되는 것을 발견 한 스크립트 변형 (한 경우 첫 번째 .01 초 직후) .. 그것은 내 배쉬 학습 곡선의 모든 부분입니다 ... 나는 당신의 대답을 좋아합니다. 그래서 나는 그것을 더 깊이 들여다 보았습니다.
Peter.O

3

그 외에도 \r또는 \b접근 방식에 따라 \033[2K 제어 문자 를 사용 하여 터미널에 전체 줄을 지우도록 지시 할 수 있습니다. 이것과 비교할 때의 이점은 삭제하려는 문자 수와 \b개수를 일치 \b시킬 \r필요가 없으며 새 줄이 이전 문자보다 짧은 경우 화면에 문자가 튀어 나오지 않는 것입니다 하나.

다음이이 질문에 적용 할 수있는 방법의 예이며, 여기에 부팅 메시지와 유사한 출력을 만들 수있는 관련 응용 프로그램의 예입니다. 이 특정 예제에서는 0 초에 도달하면 타이머가 사라지고 타이머 줄이 "준비!"로 바뀝니다. 구.

#!/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에는 존재하지 않습니다 : /
Ricky Levi

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는 적절한 패딩을 처리합니다. 우분투와 cygwin에서 테스트되었습니다.


1

캐리지 리턴을 배치하여 달성 할 수 있습니다 \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

-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.