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

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.

Related

How to run multiple instances of command-line tool in bash script? + user input for script

I am trying to launch multiple instances of imagesnap simultaneously from a single bash script on a Mac. Also, it would be great to give (some of) the arguments by user input when running the script.
I have 4 webcams connected, and want to take series of images from each camera with a given interval. Being an absolute beginner with bash scripts, I don't know where to start searching. I have tested that 4 instances of imagesnap works nicely when running them manually from Terminal, but that's about it.
To summarise I'm looking to make a bash script that:
run multiple instances of imagesnap.
has user input for some of the arguments for imagesnap.
ideally start all the imagesnap instances at (almost) the same time.
--EDIT--
After thinking about this I have a vague idea of how this script could be organised using the ability to take interval images with imagesnap -t x.xx:
Run multiple scripts from within the main script
or
Use subshells to run multiple instances of imagesnap
Start each sub script or subshell in parallel if possible.
Since each instance of imagesnap will run until terminated it would be great if they could all be stopped with a single command
the following quick hack (saved as run-periodically.sh) might do the right thing:
#!/bin/bash
interval=5
start=$(date +%s)
while true; do
# run jobs in the background
for i in 1 2 3 4; do
"$#" &
done
# wait for all background jobs to finish
wait
# figure out how long we have to sleep
end=$(date +%s)
delta=$((start + interval - end))
# if it's positive sleep for this amount of time
if [ $delta -gt 0 ]; then
sleep $delta || exit
fi
start=$((start + interval))
done
if you put this script somewhere appropriate and make it executable, you can run it like:
run-periodically.sh imagesnap arg1 arg2
but while testing, I ran with:
sh run-periodically.sh sh -c "date; sleep 2"
which will cause four copies of "start a shell that displays the date then waits a couple of seconds" to be run in parallel every interval seconds. if you want to run different things in the different jobs, then you might want to put them into this script explicitly or maybe another script which this one calls…

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

How to know if a.sh is executing from b.sh?

I am running a script a.sh and parallelly I am executing b.sh. Now b.sh should not start executing it's business logic unless a.sh is finished. To achieve that in b.sh, I have a while loop which searches with the name a.sh in ps -ef command, but a.sh has many sleep commands, so when sleep is executing I am not seeing any result in ps -ef command for a.sh, rather the process is like sleep 60
In this scenario, what I can think of is either I set a flag in a.sh which b.sh can access somehow. But I don't know how to access such variable in b.sh because a.sh is not calling b.sh.
Or I can create a child process and give it a custom name and terminate it in the end of a.sh.
In such way, in b.sh I can search for the process with that particular name and till the time it is there I don;t start execution of the business logic in b.sh. But I don't know how to do this either.
Why not let the 2 communicate? For example what you could do :
a.sh writing into some temporary file its progress status
b.sh loop reading the file waiting to see the correct thing in that file to progress.
Note that there might be some easier/safer way to do that in bash (using signals maybe) but I think that should do the job. Be careful though about the concurrent aspect of your problem.
(can't comment not enough rep)

Clarification regarding shell script scheduling

I have 2 shell scripts say a.sh and b.sh scheduled in cron where the first one a.sh is scheduled to run at 5am and the second script b.sh will run at 7am.
There are pre-conditions which state that :
1) Only one can run at a time.
2) The second script b.sh should run only after the first script a.sh completes.
Now the problem is the first script a.sh may complete its execution before 7am or may exceed 7am in some cases and in the case where it exceeds 7am the second script is also started which will break one of the pre-conditions.
Here I cannot start the second script later that day as its very crucial script.
Here how can I make both the scripts run one after the other without the first script stepping on the second script.
Have the a.sh script create a lockfile when it's complete (last line).
touch ~/a.lck
At the beginning of b.sh:
if [ ! -f ~/a.lck ]; then
exit 1 #or whatever you want it to do if the lock file is not there.
fi
Don't forget to rm the lockfile either at the beginning of a.sh or the end of b.sh!

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

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)

Resources