0

i want to build a time elapse function inside a script to print that time every second for example the output should look like below:

finding files inside a directory
time elapse HH:MM:SS
  • HH is hour
  • MM is minute
  • SS is second

and the line time elapse etc keeps counting up 1 second on the screen without printing a new line after the script is finished executing the function stops.

closed as unclear what you're asking by andcoz, meuh, Archemar, Thomas, slm Jul 24 '18 at 16:25

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    OK, so what part of it is giving you trouble? What do you have so far? What works? What doesn't work? Please edit your question and show us your code so we don't give you information you already have. – terdon Jul 24 '18 at 8:55
  • i can echo the date like this date '+%H%M%S' but how can i count up the seconds – ammar Jul 24 '18 at 8:57
  • 3
    As I said before, please edit your question and show us the code you have, what works and what you need help with. – terdon Jul 24 '18 at 8:58
1

I would write a stopwatch function, like the one I have posted here, and call it telling it to watch the process id of the command you're running (note that this assumes GNU date):

#!/bin/bash

stopwatch(){
    date1=`date +%s`; 
    while kill -0 $1 2>/dev/null; do 
        printf "Elapsed time: %s\r" "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)";
        sleep 0.1
    done
}

find /path/to/dir > output 2> error  &
stopwatch $!

Note that this approach means that if you kill the script with Ctrl+C, the find process will keep running in the background. Stéphane's solution is a better idea.

  • That assumes GNU date. Note that bash's printf has builtin support for timestamp formatting. – Stéphane Chazelas Jul 24 '18 at 9:28
  • thanks dude it really works perfectly another thing can i put the pid of the script directly like stopwatch PID – ammar Jul 24 '18 at 10:06
  • @ammar yes, $! is a PID, it's the PID of the last process launched by n the background. – terdon Jul 24 '18 at 10:08
  • no i mean by PID is the PID of the whole script not the last command – ammar Jul 24 '18 at 10:28
  • @ammar this is precisely why I asked you to show us the code you had. So we don't do this sort of back and forth in the comments. I don't understand what you mean, nor why you would want it, but yes, you can give the script's PID ($$). But that will just keep running for ever until you kill the script. You might want to ask a new question, showing your code and explaining what you need in more detail. – terdon Jul 24 '18 at 10:30
1

With the bash shell, you could do something like:

elapse() (
  SECONDS=0
  while read -t1; (($? > 128)); do
    TZ=UTC0 printf >&2 '\rtime elapse %(%T)T' "$SECONDS"
  done
  echo >&2
)

{ long-running-command 4>&1 >&3 3>&- | elapse; } 3>&1
  • And, unlike mine, this will kill any child processes if you Ctrl+C out of the script, right? – terdon Jul 24 '18 at 9:25
  • ^C sends SIGINT to the whole process group, so in yours like in mine, it should kill all processes spawned by the script. – Stéphane Chazelas Jul 24 '18 at 9:27
  • That's what I would expect, but I tested with a find & sent to the background in the script, and Ctrl+C kills the script and the timer but not the find. – terdon Jul 24 '18 at 9:28
  • @terdon, oh yes, you're right, commands started with & ignore SIGINT. – Stéphane Chazelas Jul 24 '18 at 9:33
  • @Isaac, no, elapse would eat what the command writes on its fd 4 (nothing as it's not meant to touch that). The writing end of the pipe is moved to the fd 4, while the original stdout is restored through the fd 3. The timing information is written on stderr as is customary for this kind of progress output. – Stéphane Chazelas Jul 24 '18 at 12:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.