Reputation: 795
I'm running a shell script in Linux Mint that calls some processes taking few minutes. For each process I want to echo a message like this:
echo "Cleaning temporary files... X seconds."
myprocess
where X is the current elapsed time and I would like it to change every second, but not printing a new line.
Is there a good way to do that? I only found ways to print the total time in the end, but not the elapsed time while running the process.
Upvotes: 7
Views: 4442
Reputation: 14900
You'll have to run the process in the background with &
, otherwise the rest of the script will wait until it finishes. Use backspaces to overwrite your current line, so make sure you don't use newlines.
So, to do what you want:
myproc &
myPid=$! # save process id
tmp=""
while true; do
if kill -0 "$myPid"; then # if the process accepts a signal, keep waiting
for i in {0..${#tmp}..1}; do
printf "%b" "\b" # print backspaces until we have cleared the previous line
done
tmp=$( printf "Cleaning temp files... %t seconds." )
printf "%s" "$tmp"
else
break # drop out of the while loop
fi
sleep 1
done
Upvotes: 1
Reputation: 2524
Use this at the beginning of your script, this creates a subprocess which runs in background and keeps on updating the status.
file=$(mktemp)
progress() {
pc=0;
while [ -e $file ]
do
echo -ne "$pc sec\033[0K\r"
sleep 1
((pc++))
done
}
progress &
#Do all the necessary staff
#now when everything is done
rm -f $file
Upvotes: 10
Reputation: 3791
Here is a way to have awk print on STDERR every seconds. You should just add:
The loop part (without the termination test... so "infinite loop" until CTRL-C) is:
ping 127.0.0.1 | awk '
BEGIN{cmd="date +%s"; cmd|getline startup ; close (cmd) }
/bytes from/ { cmd | getline D ; close (cmd) ;
print D-startup | "cat >&2" }'
now you just need to use "printf" and ansi escape sequence to print without a newline, have the ansi-escape go back until the beginning of the number, and flush the output (all descriptors) by invoking system:
ping 127.0.0.1 | awk -v getback4char="$(printf '\033[4D')" '
BEGIN{cmd="date +%s"; cmd|getline startup ; close (cmd) ; printf "Elapsed time: ";}
/bytes from/ { cmd | getline D ; close (cmd) ;
printf "%4d%s" ,(D-startup) , getback4char | "cat >&2"
system("") }'
note: this is compatible with all version of awk I know of, even ANCIENT ones (ie, not gawk/nawk only, but also the venerable awk.)
Upvotes: 0
Reputation: 10947
You can run each command with time:
time <command>
and then use sed/awk to exctract the elapsed time.
Upvotes: 0