1

I am not a good bash scripter yet.

In the following example script, I am trying to move through steps, check the amount of time elapsed since the step started, and use the correct singular or plural ending to describe the amount of time that has passed.

If the amount of time that passes rounds off to 1 second, I would like the script to tell me it took 1 "second" to move through the step and if it is anything else besides 1 second, I would like it to tell me it took x amount of "seconds"

#!\bin\bash
STEP=0
STEPS=4
RUN=1

while [ $RUN -eq 1 ]
do
    if (( RUNTIME == 1 ))
    then
      SEC="second"
    else
      SEC="seconds"
    fi


    STEP=$(( STEP + 1 ))
    printf "\\nStep $STEP/$STEPS\\n"
    printf "Hi!\\n"
    TIME=$SECONDS
    RUNTIME=$(( TIME - START_TIME ))
    printf "That took $RUNTIME $SEC\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 1s
    TIME1=$SECONDS
    RUNTIME=$(( TIME1 - TIME ))
    printf "That took $RUNTIME $SEC\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 2s
    TIME2=$SECONDS
    RUNTIME=$(( TIME2 - TIME1 ))
    printf "That took $RUNTIME $SEC\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 3s
    TIME3=$SECONDS
    RUNTIME=$(( TIME3 - TIME2 ))
    printf "That took $RUNTIME $SEC\\n\\n"

    END_TIME=$SECONDS
    RUNTIME=$(( END_TIME - START_TIME ))
    printf "The script took $RUNTIME $SEC to complete.\\n\\n"

    RUN=0

done
sorak
  • 2,607
  • 2
  • 16
  • 24
David Moore
  • 90
  • 1
  • 8
  • At top, `START_TIME=$(date +%s)`, then do the same for `TIME=$(date +%s)`. (`date +%s` gives the number of seconds since epoch (Jan 1, 1970)) – David C. Rankin Feb 28 '18 at 03:56
  • Oh, in this case, my question isn't about the time so much. I have figured several ways to count. The issue at hand is primarily that if the script tells me that I had "0 seconds pass" "1 seconds pass" and " 2 seconds pass" "1 seconds" should actually be written as "1 second" per the script but it does not happen and I can't figure out how to make a variable (second|seconds) change based on what the time value is equal to. – David Moore Mar 01 '18 at 01:28
  • Oh, I see the issue. Let me ask you this. *"What value of `$RUNTIME` are you using to set `$SEC`?"* (you see the *"chicken or the egg?"* issue?) Also, it's `#!/bin/bash`, NOT `#!\bin\bash` (unless you are on WSL and then I'm not sure that works either) – David C. Rankin Mar 01 '18 at 07:10

1 Answers1

1

David, if you haven't found the issue yet, it's more o chicken-or-egg issue. Meaning you are setting SEC based on the value of RUNTIME at the beginning of the loop as opposed to the current value of RUNTIME immediately prior the output. A better way to handle this, rather than computing SEC at the top of the loop, is simply to write a small function that outputs either "second" or "seconds" based on the value of RUNTIME and incorporate that into your printf (which if you are not on WSL should not include double \\ within the format string -- though from your use of it, it looks like you are)

You could do something simple like:

#!/bin/bash

STEP=0
STEPS=4
RUN=1

secorsecs () {              ## simple sec or secs function based on $RUNTIME
    local seconds="second"  ## your base output is "second"
    if (( RUNTIME != 1 ))   ## if RUNTIME != 1
    then
        seconds+="s"        ## append an "s" to the end
    fi
    printf "%s" "$seconds"  ## output result
}

while [ $RUN -eq 1 ]
do
    STEP=$(( STEP + 1 ))
    printf "\\nStep $STEP/$STEPS\\n"
    printf "Hi!\\n"
    TIME=$SECONDS
    RUNTIME=$(( TIME - START_TIME ))
    printf "That took $RUNTIME $(secorsecs)\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 1s
    TIME1=$SECONDS
    RUNTIME=$(( TIME1 - TIME ))
    printf "That took $RUNTIME $(secorsecs)\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 2s
    TIME2=$SECONDS
    RUNTIME=$(( TIME2 - TIME1 ))
    printf "That took $RUNTIME $(secorsecs)\\n\\n"

    STEP=$(( STEP + 1 ))
    printf "Step $STEP/$STEPS\\n"
    printf "Hi!\\n"
    sleep 3s
    TIME3=$SECONDS
    RUNTIME=$(( TIME3 - TIME2 ))
    printf "That took $RUNTIME $(secorsecs)\\n\\n"

    END_TIME=$SECONDS
    RUNTIME=$(( END_TIME - START_TIME ))
    printf "The script took $RUNTIME $(secorsecs) to complete.\\n\\n"

    RUN=0

done

Example Use/Output

$ bash seconds.sh

Step 1/4
Hi!
That took 0 seconds

Step 2/4
Hi!
That took 1 second

Step 3/4
Hi!
That took 2 seconds

Step 4/4
Hi!
That took 3 seconds

The script took 6 seconds to complete.

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85