You are not logged in.
Pages: 1
Hi everybody,
I know that some people here write or use bash scripts, and there's recently been a thread about alarm clock scripts.
https://forums.bunsenlabs.org/viewtopic.php?id=6257
Here's something similar; I've been looking for a way to have a simple, unobtrusive countdown timer, and came across this script (which works in a terminal and counts down 20 seconds at a time);
seconds=20; date1=$((`date +%s` + $seconds));
while [ "$date1" -ge `date +%s` ]; do
echo -ne "$(date -u --date @$(($date1 - `date +%s` )) +%H:%M:%S)\r";
done
I'm using it now and can testify that it works.
Here's a thread with some more and similar ideas in it;
https://superuser.com/questions/611538/ … a-terminal
Last edited by Colonel Panic (2021-03-26 19:11:15)
Offline
Thanks
Offline
... bash ... works in a terminal and counts down 20 seconds at a time ...
seconds=20; date1=$((`date +%s` + $seconds));
while [ "$date1" -ge `date +%s` ]; do
echo -ne "$(date -u --date @$(($date1 - `date +%s` )) +%H:%M:%S)\r";
done
This is actually pretty resource intensive; adding a "sleep 0.1" already reduces the strain significantly.
But why call date twice in a loop over and over when all you want is to count down seconds...
seconds=20
end_seconds=$((SECONDS+seconds))
while ((SECONDS<end_seconds)); do
printf ' %2d\r' "$((end_seconds-SECONDS))"
sleep 0.1
done
see 'man bash' => Shell variables => SECONDS.
Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos
Offline
1. An zsh oneliner attempt
c=20; repeat c {(( c-- )); sleep 1; echo $c}
2. Similar, but countdown in single line
c=20; d="$c"; echo -ne "$c\r"; repeat c {(( c-- )); sleep 1; echo -ne "${(l(2)(0))c}\r"} && echo "$d seconds has passe
d."
3. A fun one that draws a little reverse staircase using perc2 script
c=20; set +m; perc=$(( 100.0/c )); perc2 100 & repeat c {(( c-- )); sleep 1 & var="$(perc2 $(( perc * c )))" ; wait; echo "$var" }
Note: set +m disables shell monitoring, so that it will not report subshell returns.
███████████████████████████████████████████████████████████████████████████▎
█████████████████████████████████████████████████████████████████▊
████████████████████████████████████████████████████████▍
███████████████████████████████████████████████
█████████████████████████████████████▋
████████████████████████████▎
██████████████████▊
█████████▍
p.s. Both examples will not achieve millisecond precision. To test:
time ( c=20; set +m; perc=$(( 100.0/c )); perc2 100 & repeat c {(( c-- )); sleep 1 & var="$(perc2 $(( perc * c )))" ; wait; echo "$var" } )
# returns: 20.156 total on this machine.
Last edited by brontosaurusrex (2021-04-11 09:05:09)
Offline
p.s. Both examples will not achieve millisecond precision.
Because you rely on the sleep command to measure time; the other examples above actually measure the time (one with `date`, the other with the bash builtin SECONDS) while counting down.
Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos
Offline
Your version takes 19 seconds, so I guess It's superluminal?
edit: The ops version takes 20.238s
I win.
Prettyfied script version (zsh) of my 2nd example. And a progress-bar version (also zsh).
Last edited by brontosaurusrex (2021-04-11 13:08:51)
Offline
^There is always timeout
#!/bin/bash
function _exit {
stty sane
echo -ne "\e[?25h"
}
trap "_exit" EXIT
echo -ne "\e[?25l"
function _main {
function _pbar {
let _progress=(${1}*100/${2}*100)/100
let _done=(${_progress}*2)/10
let _left=20-$_done
_fill=$(printf "%${_done}s")
_empty=$(printf "%${_left}s")
printf "\r%s[%3d%%]%s\r" "${_fill// /▇}" "${_progress}" "${_empty// /▇}"
}
_end=200
for _n in {200..0}
do
sleep 0.1
_pbar ${_n} ${_end}
done
}
export -f _main
timeout --signal INT 20s bash -c _main
Што ни оштровиди ум сагледати не може - љубав превазилази.
Offline
Your version takes 19 seconds, so I guess It's superluminal?
edit: The ops version takes 20.238s
I win.
Prettyfied script version (zsh) of my 2nd example. And a progress-bar version (also zsh).
My version takes 19s because it stops 1s early.
But the logic of my argument stands: since you never know how long actual script execution takes, you cannot rely solely on the sleep delays to measure time. It will get less precise the longer it runs.
(My version also uses sleep, but only to keep it from taking 100% CPU, not to measure time.)
But whatever, just continue faffing around with your version. It sure is prettier.
Last edited by ohnonot (2021-04-12 04:45:24)
Please use CODE tags for code.
Search youtube without a browser: repo | thread
BL quote proposals to this thread please.
my repos / my repos
Offline
you cannot rely solely on the sleep delays to measure time.
Yes, you can.
Most of the delay originates from writing to the terminal, not from sleep command.
Sleep 1 is always one second. It's that printf adds extra time.
time sleep 1
real 0m1,004s
user 0m0,000s
sys 0m0,003s
Sleep does nothing else but sleeping.
So sleep is only wasting time, so to say.
That sleeping time can be spent in other ways,
e.g. printing to the terminal and counting seconds.
The trick is to to to run sleep in the background,
then move to the next command that writes to the terminal and wait until the subshell exits.
ctdown() {
seconds=20
while [ $seconds -gt 0 ] ; do
sleep 1 &
printf "\r%2d" "${seconds}"
seconds=$((seconds-1))
wait
done 2>/dev/null
}
time ctdown
1
real 0m20,073s
user 0m0,039s
sys 0m0,033s
Edit: It's fine for 20 seconds, on the other hand it's almost a second late on a 120second countdown.
Yours is preety accurate no matter what sleep time 1 or 0.1s with bronto's sleep.
ctdown() {
seconds=120
end_seconds=$((SECONDS+seconds))
while ((SECONDS<end_seconds)); do
sleep 1 &
printf ' %3d\r' "$((end_seconds-SECONDS))"
wait
done 2>/dev/null
}
time ctdown
1
real 1m59,627s
user 0m0,208s
sys 0m0,216s
Even hurries a little.
Without a further delay, I declare a tie between Bronto and Not.
Last edited by misko_2083 (2021-04-12 15:04:51)
Што ни оштровиди ум сагледати не може - љубав превазилази.
Offline
Uhmm, ok, still you two are doing low-level stuff in bash script, my 1st script reports 0% cpu usage for example. I'am fine with tie, little reluctant, but ok
Offline
^Avoiding the zombie shell apocalypse.
You people aleady pulled your war axes.
Last edited by misko_2083 (2021-04-13 04:43:53)
Што ни оштровиди ум сагледати не може - љубав превазилази.
Offline
Doing some 'research', this one is neat (and correct and low cpu)
https://github.com/trehn/termdown (pip install termdown)
Similar in go (super correct)
https://github.com/antonmedv/countdown
time countdown 25s -up
countdown 25s -up 0.02s user 0.00s system 0% cpu 25.011 total
Last edited by brontosaurusrex (2021-04-13 09:23:28)
Offline
Pages: 1