我正在尝试制作一个秒表,当用户按 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