Link to home
Start Free TrialLog in
Avatar of projects
projects

asked on

bash random 24hr event

Using bash, I want to have a function which runs every X amount of time but within a range.
For example, a variable which might be set to 12hrs or 24hrs.

However, I want the function to be randomly set off, between one hour before or after the 24hr period. In other words, I need an event which runs approximately every X amount of time but not exactly on that time.

Looking for bash code as a solution.

Thanks.
Avatar of ozo
ozo
Flag of United States of America image

while sleep $((82800+RANDOM%7200)) ; do function ; done
Avatar of projects
projects

ASKER

Could this be added inside of a script which has multiple functions?
SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Darn, turns out this won't work on the device I am using for testing.
I don't have any bc package available and there is an error.

# ./rand
./rand: line 27: bc: command not found
./rand: line 30: 7200+: syntax error: operand expected (error token is "+")
What 'device' would that be? If it doesn't even support this line: sleep $((${PERIODS}+${OFFSETS})) then it's going to be hard to calculate anything. You did not test before you accepted a solution? A $((expression)), - and + are supported in bash (see man page).
In this case, it is on an openwrt router.
I usually test the solution before hand but in this case, I failed to do that.
Does the router run bash?  If not, does it use some other scripting language?
yes, bash, but no bc and what ever caused that second error.
@Gerwin, show me how to test this in a simple bash script and I can post the results.
while sleep $((82800+RANDOM%7200)) ; do function1 ; function2 ; function3 ; done
does not use bc
>> what ever caused that second error
The second error is caused by this line:

$((${PERIODS}+${OFFSETS}))

this is just basic arithmetic in bash, try if this works on your router"

PERIODS=2
OFFSETS=10
echo $((${PERIODS}+${OFFSETS}))

you should get 12 as a result. If that doesn't work then you don't have a normal bash shell. What do you get from:

bash --version
If the bc failed, and $OFFSETS was blank, then
sleep $((${PERIODS}+${OFFSETS}))
would be
sleep $((7200+))
which would cause an error in a normal bash shell
But a normal bash shell should not need to do
$(echo "scale=0 ; (-16384 + ${RANDOM}) * 3600 / 32768 * ${OFFSETH} " | bc -l)
if it could just do
$(( (-16384 + ${RANDOM}) * 3600 / 32768 * ${OFFSETH} ))
@Gerwin; I get a 12.

I know it's pretty standard bash, just doesn't have as many tools as normal since this is just a small embedded device.

# bash --version
GNU bash, version 4.2.53(1)-release (mips-openwrt-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
So the problem is bc not bash, but you don't need bc when you have bash arithmetic.
@ozo - Correct, code with your modified line:
while :
do
  # variable
  PERIODH=12
  PERIODS=$((${PERIODH}*3600))

  # offset (2 meaning +/- 1 hour)
  OFFSETH=2
  OFFSETS=$(( (-16384 + ${RANDOM}) * 3600 / 32768 * ${OFFSETH} ))

  # wait before launch
  sleep $((${PERIODS}+${OFFSETS}))

  echo "Put your function call here"
done

Open in new window


works in bash :)
Can you change the timer to seconds so I can test this?
All the timers suggested here sleep in seconds.
LOL, yes, just noticed that :)
PERIODH = PERIOD in Hours
PERIODS = PERIOD in Seconds

etc. :D