views:

51

answers:

4

First of all, I'm a beginner on shell-script. This code I've done is not working.

I want to repeat a code for 30 seconds but it doesn't work. It just keep doing my logic indefinitely.

DIFF=0

while [ $DIFF < 30 ]; do

    START=$(date +%s)

######## My logic #########

    DIFF=$(( $END - $START ))
    echo $DIFF
    cd ..
    sleep 5s

done

I think it's because I'm not doing the while clause properly?

+2  A: 

Well, you definitely need to provide some values for $START and $END. They won't set themselves!

You may want to do something like

START = `date +%s` 

to set it to a time in seconds. Of course END will need to be set inside your loop to get it updated.

EDIT: cd .. is hopefully not really what you plan to run inside the loop. Within a few milliseconds your current directory will be the root directory, with little else accomplished. It would be cheaper to do a single cd / .


EDIT 2: This shouldn't be such a hard problem. For this edit, I've built and tested a one-line solution:

START=$(date +%s); DIFF=0; while [ $DIFF -lt 30 ]; do echo $DIFF; DIFF=$(($(date +%s)-$START)); done

That will correctly update its variables and display them... and it ends after 30 seconds.

Carl Smotricz
Thanks....But it was already done... sorry I made a mistake when I postate it...As you can notice I do an "echo $DIFF" so it shows me the DIFF value it's really going okay with the $DIFF value but the computer stays on the loop when DIFF is 200 ... 300 and so on.
Alucard
Why did you remove the OP's beautiful `$()` and replace it with ugly `\`\``? And spaces around the equal sign won't work, by the way.
Dennis Williamson
@Dennis Williamson: Because I'm no shell script expert and wasn't aware of the subtleties - thanks for the info! In my defense, the OP had no beautiful `$()` when I wrote my post; he edited that in later, I think.
Carl Smotricz
Your solution works, Carl !thanks...
Alucard
+1  A: 

It looks like you're using bash.

Try something like this perhaps:

START=...
while (($DIFF<30)); do
   #   ....
   DIFF=$((END-START))
done

(See Bash arithmetic evaluation and The Double-Parentheses Construct.)

Bruno
Sorry, I had misread an important point of course. As Carl Smotricz mentioned in his answer, don't reset START within the loop.
Bruno
"# assigment ($ only outside)" or not at all: `(( DIFF = END - START ))` and `(( DIFF < 30 ))` Note that the double-parentheses permits spacing around operators/operands.
Dennis Williamson
Hum... not by best answer, sorry. You're right. I've edited to remove my incorrect comments. Hopefully, the pointers might be useful to the original poster at least.
Bruno
+1  A: 

use an infinite loop. an example pseudocode

DIFF=0
while true
do
  START=$(date +%s)
  END=.... #define your end
  DIFF=$((END-START))
  if [ "$DIFF" -gt 30 ] ;then
    break
  fi
  .....
done
ghostdog74
+2  A: 
((end = $(date +%s) + 30))
while (( $(date +%s) < end ))
do
    something
done

Or, using the builtin variable $SECONDS in Bash:

((end = SECONDS + 30))
while (( SECONDS < end ))
do
    something
done
Dennis Williamson
Ooh, there's a `$SECONDS` ? Spiffy, that's a nice thing to know. +1.
Carl Smotricz