키를 누를 때까지 무언가를 출력합니다(루프).

키를 누를 때까지 무언가를 출력합니다(루프).

사용자가 QI를 누르고 종료하려고 할 때 스톱워치를 만들려고 합니다.

두 개의 스크립트를 찾았는데 그 중 하나는 ctrl+z를 누르기 전에 시계를 표시합니다. "q"를 누르면 종료되는 스크립트도 있습니다.

나는 그것들을 결합하려고 노력했지만 "읽기"가 모든 것을 엉망으로 만드는 것 같습니다.

이것을 구현하려는 이유는 사용자가 Q를 누르면 경과 시간이 파일에 저장되기 때문입니다.

스톱워치:

BEGIN=$(date +%s)

echo Starting Stopwatch...

while true; do
   NOW=$(date +%s)
   let DIFF=$(($NOW - $BEGIN))
   let MINS=$(($DIFF / 60))
   let SECS=$(($DIFF % 60))
   let HOURS=$(($DIFF / 3600))
   let DAYS=$(($DIFF / 86400))

   # \r  is a "carriage return" - returns cursor to start of line
   printf "\r%3d Days, %02d:%02d:%02d" $DAYS $HOURS $MINS $SECS
   sleep 0.25
done

q에서 종료:

while true; do
    echo -en "Press Q to exit \t\t: "
    read input
    if [[ $input = "q" ]] || [[ $input = "Q" ]] 
        then break 
    else 
        echo "Invalid Input."
    fi
done

PS: 저는요매우이것에 익숙하지 않습니다.

답변1

아마도 이것이 당신에게 도움이 될 것입니다. 나는 그것들을 하나로 통합했지만 약간의 수정을 가했습니다. 이것이 결과입니다.

BEGIN=$(date +%s)

echo Starting Stopwatch...
echo Press Q to exit.

while true; do
    NOW=$(date +%s)
    let DIFF=$(($NOW - $BEGIN))
    let MINS=$(($DIFF / 60))
    let SECS=$(($DIFF % 60))
    let HOURS=$(($DIFF / 3600))
    let DAYS=$(($DIFF / 86400))

    # \r  is a "carriage return" - returns cursor to start of line
    printf "\r%3d Days, %02d:%02d:%02d" $DAYS $HOURS $MINS $SECS

# In the following line -t for timeout, -N for just 1 character
    read -t 0.25 -N 1 input
    if [[ $input = "q" ]] || [[ $input = "Q" ]]; then
# The following line is for the prompt to appear on a new line.
        echo
        break 
    fi
done

보시다시피 sleep첫 번째 스크립트의 명령을 두 번째 스크립트로 바꿨습니다. 시간 제한에는 이제 read지연 기능이 있습니다. -N첫 번째 키를 누른 후 read기다리지 않고 반응하려면 이 옵션이 필요합니다.Enter

답변2

나는 더 단순한 것을 선호합니다 until...

until read -s -n 1 -t 0.01; do 
    echo -n "."
    sleep .5
    done 
echo 

유일한 사소한 문제는 단일 문자가 표시된다는 것입니다.

답변3

에서 영감을 받다이 답변, read-t옵션과 함께 사용하면 무기한 대기하는 대신 지정된 시간 동안만 대기할 수 있습니다. 아래 코드는 게시한 두 조각을 결합합니다.

#!/bin/bash

begin=$(date +%s)
echo "Starting Stopwatch... Press q to exit"
while true; do
   now=$(date +%s)
   diff=$(($now - $begin))
   mins=$(($diff / 60))
   secs=$(($diff % 60))
   hours=$(($diff / 3600))
   days=$(($diff / 86400))

   # \r  is a "carriage return" - returns cursor to start of line
   # with \33[2K we clear the current line
   printf "\33[2K\r%3d Days, %02d:%02d:%02d" $days $hours $mins $secs

   # -n 1 to get one character at a time, -t 0.1 to set a timeout 
   read -n 1 -t 0.1 input                  # so read doesn't hang
   if [[ $input = "q" ]] || [[ $input = "Q" ]] 
   then
      echo # to get a newline after quitting
      break
   fi
done

관련 정보