Running a shell script once a day at random time [duplicate] - bash

This question already has answers here:
Cron jobs and random times, within given hours
(13 answers)
Closed 9 years ago.
Need run a shell script once a day at random time. (so once every day between 00:00-23:59).
I know the sleep command, and the cron too, but
the cron has not random times
and the sleep solution - not very nice - my idea is launch the script every midnight and sleep random time at the start of the script.
Is here something more elegant?

If you have the at command, you can combinte the cron and the at.
Run from a cron every midnight the next script:
#!/bin/bash
script="/tmp/script.sh" #insert the path to your script here
min=$(( 24 * 60 ))
rmin=$(( $RANDOM % $min ))
at -f "$script" now+${rmin}min
The above will run the at command every midnight and will execute your script at random time . You should check your crontab how often is the atrun command started. (The atrun runs the commands stored with the at)
The main benefit in comparison with the sleep method: this "survives" the system reboot.

I would simply launch you script at midnight, and sleep for a random time between 0 and 86400 seconds. Since my bash's $RANDOM returns a number between 0 and 32767:
sleep $(( ($RANDOM % 1440)*60 + ($RANDOM % 60) ))

The best alternative to cron is probably at
See at man page
Usually, at reads commands from standard input, but you can give a file of jobs with -f.
Time wise, you can specify many formats. Maybe in your case the most convenient would be
at -f jobs now + xxx minutes
where your scripts gives xxx as a random value from 1 to 1440 (1440 minutes in a day), and jobs contains the commands you want to be executed.

Nothing prevents you from running sed to patch your crontab as the last thing your program does and just changing the next start time. I wouldn't sleep well though.

You can use cron to launch bash script, which generates pseudorandom timestamp and gives it to unix program at
I see you are familiar with bash and cron enough, so at will be a piece of cake for you. Documentation as always "man at" or you can try wiki
http://en.wikipedia.org/wiki/At_(Unix)

Related

Bash script calling Python with sleep

I want to call a Python file named main.py using a bash script in the same folder.
Bash script must call the Python file randomly between 2pm and 6pm once a day.
I would use a random sleep.
NOTE: it should be executed randomly. For example starting at 0 seconds of the minute is not a random time!
How would you write this bash script to achieve this functionality?
This code can help. It runs the python script in a random minute between the interval you want to. Also this bash script should be added to crontab file to be scheduled at 02.00PM.
#!/bin/bash
maxtime=$((4*60*60))
delay=$(($RANDOM%maxtime))
(sleep $((delay)); /usr/bin/python /path/to/yourscript.py) & #background the sleep process, then run your script
You could use cron to run the bash script #1400, and the bash script would have a random number of minutes to sleep less than 240 (4 hours * 60 minutes). When sleep runs out, call the python.
I assume you know about $RANDOM?
#!/bin/bash
sleep $(( $RANDOM % 240 ))m
./mypython.py
To account for new constraints in the edit:
#!/bin/bash
sleep $(( $RANDOM % 240))m
sleep $(( $RANDOM % 60))
./mypython.py

Need to write a script that runs two scripts, but needs to stop the first one before the 2nd runs [duplicate]

This question already has answers here:
Timeout a command in bash without unnecessary delay
(24 answers)
Closed 6 years ago.
This is a CentOS 6.x box, on it I have two things that I need to run one right after the other - a shell script and a .sql script.
I want to write a shell script that calls the first script, lets it run and then terminates it after a certain number of hours, and then calls the .sql script (they can't run simultaneously).
I'm unsure how to do the middle part, that is terminating the first script after a certain time limit, any suggestions?
script.sh &
sleep 4h && kill $!
script.sql
This will wait 4 hours then kill the first script and run the second. It always waits 4 hours, even if the script exits early.
If you want to move on immediately, that's a little trickier.
script.sh &
pid=$!
sleep 4h && kill "$pid" 2> /dev/null &
wait "$pid"

Write a timer in shell script to trigger/run another prepared script

Can anyone give me a hint how to write a timer shell script so that, e.g. once it's got to tomorrow midnight, it will run other scripts that are already prepared in the same directory. Thanks a lot.
If you don't have the ability to use cron or at, you can do this with a script. The key commands are sleep to kill time and date to get the current time. Something like (untested sh script):
while sleep 600; do
time=$(date +%H)
if [ ${time} = '00' ]; then
echo Now is the time
break
fi
done
This technique allows running scripts periodically on systems where cron and at access is disabled. The break is for one time use. Adjust the sleep time to meet your needs. date can return any number of variables that can be used to decide if the desired time has arrived. For simple perodic runs the if statement can be removed.

Run variable length bash script at the top of the hour without cron

I have a simple bash script that runs some tasks which can take varying amounts of time to complete (from 15 mins to 5 hours). The script loops using a for loop, so that I can run it an arbitrary number of times, normally back-to-back.
However, I have been requested to have each iteration of the script start at the top of the hour. Normally, I would use cron and kick it off that way, every hour, but since the runtime of the script is highly variable, that becomes trickier.
It is not allowable for multiple instances of the script to be running at once.
So, I'd like to include the logic to wait for 'top of the hour' within the script, but I'm not sure of the best way to do that, or if there's some way to (ab)use 'at' or something more elegant like that. Any ideas?
You can still use cron. Just make your script use a lock file. With the flock utility you can do:
#!/bin/bash
exec 42> /tmp/myscriptname.lock
flock -n 42 || { echo "Previous instance still running"; exit 1; }
rest of your script here
Now, simply schedule your job every hour in cron, and the new instance will simply exit if the old one's still running. There is no need to clean up any lock files.

How to start a shell script in one minute later in linux?

How to start a shell script in one minute later?
Suppose there are two bash files a.sh and b.sh
I want to execute b.sh one minute(or several seconds) after a.sh executed.
what should I code in a.sh ?
Simple. you want to use 'at' to schedule your job. and 'date' to calculate your moment in the future.
Example:
echo b.sh | at now + 1 minute
or:
echo b.sh | at -t `date -v+60S "+%Y%m%d%H%M%S"`
-v+60S adds 60 seconds to current time. You can control exactly how many seconds you want to add.
But usually, when people wants one program to launch a minute after the other, they are not 100% sure it will not take more or less than a minute. that's it. b.sh could be launched before a.sh is finished. or a.sh could have finished 30 seconds earlier than "planned" and b.sh could have started faster.
I would recommend a different model. Where b.sh is launched first.
a.sh creates a temp file when it starts. execute is tasks and delete its temp file at the end.
b.sh watch for the temp file to be created, then deleted. and start its tasks.
Make the final line of a.sh:
sleep 60 && b.sh
(If b.sh is not in a directory in PATH, make that a full path to b.sh.)
You can just sleep:
a.sh
sleep 60
b.sh
Or for more complicated cases you can use the at command:
echo b.sh | at now + 1 minute
See the at man page for more information.
Use the at command.
See man at for how to use it.
You could use the command to sleep your script for 1 minute.
sleep 1m
Then when you wish to call the 2nd script
bash a.sh
If you want to execute the second script some number of seconds after the start of the first script, you can do this in the first:
b.sh &
and this in the second:
sleep 10
# more commands
You could pass the number of seconds as an argument from the first to the second.
Unfortunately, at doesn't do time increments finer than one minute.
Schedule both the scripts to run at the same time in cron and put the required delay in b.sh.

Resources