How to call another shell script from a shell script in Linux - linux

I am trying to create one wrapper script to trigger the parent script at 6AM only. But it is not properly working. It always showing Do Nothing and else part is looping without exit. Can any one help?
I want to check if the time is 6 AM and also need to check the string from text file(status). if both conditions are satisfied my parent script should execute via this wrapper script.
Below is the script
path= $(cat /home/avj/)
mode= $(cat /home/avj/status)
checktime="060000"
echo $checktime
echo $currentTime
while true
do
currentTime=date +"%H%M%S"
if [[ $currentTime -eq $checktime && $status == running ]];
then
sh &path/parent.sh
else
echo Do Nothing
fi
done

Usually on Linux, you use crontab for this kind of scduled tasks. But you have to specify the time when you "set up the timer" - so if you want it to be configured in the file itself, you will have to create some mechanism for this.
For example, you can add crontab
30 1 * * 5 /path/to/script/script.sh
Will execute the script every Friday at 1: 30 (AM) here:
30 is minutes
1 is an hour
the next 2 * are the day of month and month (in that order), and the 5th is the day of the week

Related

How to write a bc calculated variable to file using CRON jobs (linux, bash, script, cron)

I am a lot confused about this behavior.
Each time I run this script from terminal, it works fine, but it fails once is executed from a crontab.
Inside the script you can find each step description.
The target is to print date and time with the peso variable to a file.
I have changed line 16 countless times. Same thing for line #4.
Edit for clarity: THIS IS JUST A SMALL PART FROM THE WHOLE SCRIPT.
It runs nice every minute. It does everything, except the peso issue.
Please HELP!!!
1 # Here I compute one decimal value (like z=0.123) with two integers (sd and mean)
2 peso=$( echo "scale=4; ${z}*${sd}/100 + ${mean}/100" | bc -l)
3 echo "peso_mtrx="$peso # This is for checking: shows 40.123 (example), so it is OK
4 peso+=";" # Add a semicolon to check its behaviour
5 echo "peso= "$peso # show it: OK
6 peso1=$(date "+%D %T") # Now I capture date and time
7 echo "fecha= "$peso1 # shows it, so it is OK
8 peso1+=";" # add a semicolon to date
9 peso1+=$peso # concatenate the peso variable
10 echo $(printf '%s' "$peso1") # shows it, so it is ok up to here
11 echo $(printf '%s' "$peso1") >> ~/projects/Files/normal.csv # WRITE TO FILE
12 # whenever I run this script from terminal, all variables showed right and even print all data into file.
13 # File stores a new line like: 02/03/21 08:24:40;40.1709;
14 # BUT... when it is executed from a CRON job... everything except peso are stored.
15 # File stores a line like: 02/03/21 08:24:40;; peso variable just vanishes.
16 # is it something related to subshells? how to solve this rigmarole?
As I was suspicious, the whole thing was related to subshell issues.
I just did something inside crontab.
Once I execute crontab -e, I initially had something like:
*/1 * * * * /absolute/path/to/project.sh
So doing some reading I ended up doing this:
SHELL=/bin/bash
*/1 * * * * exec bash -l /absolute/path/to/project.sh
I beg to an expert to enlighten us about this solution. As far as I do understand, it is related to create a login shell inside cron using the information stored in .bash_profile.
It did enable the environment variables to be reachable.

cron script needs conditional to run

I have two python scripts that Im trying to run on my server
I currently have process_one running through a cron job every five minutes I want to add the second script to the cron job.
I was told by the freelancer that both programs can run automatically by writing a shell script. If process_one generates data in its output_folder (i.e.
process_two's input_folder) then it will return system status "0" (OK) to the operating system, otherwise it returns a
ERROR signal - even in the case of "no errors, yet nothing new produced".
Im at a loss Ive never written shell scripts before. Im looking on here and else where but I dont know how to write this. Any help would be appreciated
/path/to process1/process_one && /path/to process2/process_two
What you have for the cron job is correct, process one will run and if successful process_two will run. The only thing that is missing is for process_two to check for new data in the process_one output directory before it runs.
I would suggest that you use a few lines at the top of process_two python script to check for recent data and exit if not found. Either you can modify the python script itself to do this, or write a bash wrapper as process_two that simply calls the python script after checking for recent data.
py
import os.path, time
fileCreation = os.path.getctime(filePath)
now = time.time()
fivemin_ago = now - 300
if fileCreation < fivemin_ago:
sys.exit "data was older than five minutes"
bash
NOW=$(date +%s)
MODIFIED=$(date -d "$(stat FILEPATH | grep Modify | awk '{print $2" "$3}')" +%s)
if [ $NOW -gt $[$MODIFIED+300] ];then
echo "data was older than five minutes"
exit 1
else
process_two.py
fi
The best way will make a third file where you can call the first script and get the return after the return you run or not the second script, it will be something like.
#!/usr/bin/env bash
variable=$(download "something")
if [-f "../path/your/file.pdf" ]; then
run here your second command // if file exists run it
fi

How to schedule a task automatically with a while loop in bash?

I'm trying to schedule my script to run at two different times and then keep running in the background waiting for the next time that the conditions are met again.
So far I am not able to do it because after that one condition is met this scripts exits automatically:
function schedule {
while :
do
hour=$(date +"%H")
minute=$(date +"%M")
if [[ "$hour" = "02" && "$minute" = "31" ]]; then
# run some script
exec /home/gfx/Desktop/myscript.sh
wait
schedule
elif [[ "$hour" = "02" && "$minute" = "32" ]]; then
# run some script
exec /home/gfx/Desktop/myscript.sh
wait
schedule
fi
done
}
schedule
The script that I execute is the following :
$cat myscript.sh
echo "this a message"
Any idea or comment are welcome, thanks!
When you do:
exec some program
something else
if the exec works, then the something else will never happen because the script is replaced by what you exec'd
Maybe instead of:
exec /home/gfx/Desktop/myscript.sh
wait
schedule
you want:
/home/gfx/Desktop/myscript.sh &
wait
# schedule -- don't make a fork bomb
As noted in the comments, & + wait is kind of silly, you probably want:
/home/gfx/Desktop/myscript.sh &
# wait
# schedule
or:
/home/gfx/Desktop/myscript.sh
# wait
# schedule
depending on whether or not you want myscript in the background.
ALSO you should put a sleep in the loop, (maybe sleep(59)) to keep it from looping like a banshee.
You begin to understand the appeal of cron I think (at least for things you don't want to interact with your terminal session).
Crontabs are best place to put these things.
Edit crontab using
$ crontab -e
Add following lines to the files
31 2 * * * /home/gfx/Desktop/myscript.sh
And save crontab file. Your script will be executed every day 2:31 am

Shell script: fire a command if system time is equal to given time

I am very new to shell scripting.
The script should fire a command if the given time as command line argument is equal to the system time, else it should wait(poll) for the given time.
I started with very basics, but i am stuck here only:-(
#!/bin/sh
now=$(date +%k%M)
cur="055" # should be given as command line arg
if ($now == $cur)
then
echo "Fire command here"
else
echo "poll for time"
fi
When i execute the script:
./script.sh: line 5: 055: command not found
poll for time
Thanks for the help.
I think the above is just a small syntax error, instead of:
if ($now == $cur)
You may want to do this:
if [ $now -eq $cur ] #very basic comparison here, you may want to have a
#look at the bash comparisons
Update
Could you change the variable to,
$cur=$(date +%H%M)
And in case the input is not provided by you, you should remove the space in front
of the $now
now=$(echo $now | sed 's/\s//g') #this removes the spaces in the input
You can run a program # a particular time with :
crontab -e
and
0 14 * * * command
to run command # 14 PM (by example)
begin="`date '+%s'`"
final=... #should be converted to seconds since epoch...
sleep $((final - begin))
exec_your_command
The problem you described seems to be exactly what crontab is designed to handle, from wikipedia "Cron is driven by a crontab (cron table) file, a configuration file that specifies shell commands to run periodically on a given schedule."
Here is a quick reference, it is reletively barebones, but should be enough to determine if it meets your needs.
Use following code
if [ $now == $cur ]

How to run script continously in background without using crontab

I have a small script that checks certain condition continously and as soon as that condition is met the program should execute. Can this be done. I thought of using crontab where script runs every 5 min but now I want that to be done without crontab
You probably want to create an infinite loop first, then within that loop you probably want to verify your condition or wait a bit. As you did not mention which scripting language you wanted to use, I'm going to write pseudo code for the example. Give us more info about the scripting language, and perhaps also the conditions.
Example in pseudo code:
# Defining a timeout of 1 sec, so checking the condition every second
timeout = 1
# Running in background infinitely
while true do
# Let's check the condition
if condition then
# I got work to do
...
else
# Let's wait a specified timeout, not to block the system
sleep timeout
endif
endwhile
Example in sh with your input code
#!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
# Defining a timeout of 1 hour
timeout=3600
while true
do
case 'df /tmp' in
" "[5-9]?%" ") rm -f /tmp/af.*
;;
*)
sleep $timeout
;;
esac
done
You can then run this script from the shell using 'nohup':
nohup yourscript &

Resources