Cron tab on linux - cron

I have an .exe setup to run every 5 minutes.It creates a file.
I have stored the users email in a mysql database. The file that get created is named after the primary key of the database.For example:
1.txt,2.txt,50.txt etc
Where 1,2,and 50 are the primary keys.
I was wondering if there was a way after the cron ran to email the users.I use php on my server.Is there some way to do this?
EDIT:
I think I can rather just set up a .php file to run on cron and use exec().

In your crontab, you can have cron entries and you can have environment variables. There is a variable called MAILTO that specifies the user that will receive the email containing any stdout or stderr from the processed jobs.
To send email to vivek#nixcraft.in, enter:
MAILTO=vivek#nixcraft.in
If MAILTO is defined but empty (MAILTO=""), no mail will be sent.
MAILTO=""
The default (if MAILTO is not set) is to email the local user who owns the crontab being executed.
I haven't tried it, but you may be able to set the email for just one of your cronjobs using something like this:
0 0 * * * /root/daily_task.sh #will email crontab owner
MAILTO=joe#gmail.com
0 1 * * * /root/other_daily_task.sh # will email joe#gmail
MAILTO=root
0 * * * * /root/hourly_task.sh #(hopefully) mails root and not joe
Anything after a # on a line is of course a comment.
Taken from http://www.cyberciti.biz/faq/linux-unix-crontab-change-mailto-settings/

Related

Using flock to lock file for X time

I am a Linux novice and currently developing a security system using Raspberry Pi 3 and MotionEye. To get notifications via e-mail, I am attempting to create a custom shell script that will send an e-mail if there is motion, lock for X minutes, then send another e-mail if there is still motion. However, I am having some difficulties.
I created a simple Python script named "send_email.py" using SMTP that works perfectly fine for sending e-mails when I execute it via command line.
The shell script (named "flock_email.sh") is where I run into troubles in a few regards:
Whenever I run flock_email.sh, it completely overwrites send_email.py. I have tried to change file permission so it is only executable by the user, but it still overwrites.
The flock command/function does not work as I intended or at all. I have looked all over the internet and tried multiple different codes, but none have worked. I have attached my various flock_email.sh scripts I have tried.
Not necessarily a problem, but I am a bit confused on what my "shebang" line should be. For flock_email.sh I have it as "!#/bin/bash", which I believe makes the script it executable, at least according to this. Do I still need to change the permissions via the command "chmod +x flock_email.sh"? The path is /home/pi, which is essentially the main directory of my Pi.
The different solutions I have tried:
In flock_email.sh, I have tried to directly change the file permissions to read-only instead of using flock, having it sleep, then changing the permissions back to allow execution of the file.
Multiple flock_email.sh implementations, as attached.
To summarize:
I need to execute send_email.py before locking the file flock_email.sh.
Once locked, it needs to stay locked for X time.
Does anyone have any pointers or suggestions? I have spent well over 15 hours tinkering with this and feel like I have gotten nowhere!
send_email.py:
#!/usr/bin/env
import smtplib
def send_email():
content = "Message I want to send to specified e-mail."
sender = "e-mail account that will send message"
pword = "password of sender"
receiver = "e-mail account that will receive message"
mail = smtplib.SMTP("smtp.gmail.com",587)
mail.ehlo
mail.starttls()
mail.login(sender,pword)
mail.sendmail(sender,receiver,content)
mail.close()
send_email()
flock_email.sh (1):
#!/bin/bash
(
python /home/pi/send_email.py
flock -e 200
sleep [time in seconds]
)
flock_email.sh (2):
#!/bin/bash
(
python /home/pi/send_email.py
exec 3>/home/pi/send_email.py
flock -x 3
sleep [time in seconds]
exec 3>&-
)
flock_email.sh (3):
#!/bin/bash
python /home/pi/send_email.py
chmod 444 /home/pi/send_email.py # modify to read only for all
sleep [time in seconds]
chmod 755 /home/pi/send_email.py # modify to rwx for owner, r-x for others
The reason why man flock and all posts say to use > is because you're supposed to use a dedicated lock file, typically in /var/lock:
#!/bin/bash
exec 3> /var/lock/motionmail
flock -ne 3 || exit
python /home/pi/send_email.py
sleep 3600
This additionally fixes you sending your email regardless, before you ever check the lock, and aborts new emails instead of queueing them all up.
You choose the lock file name based on the scope you want your lock to have:
If you only want one email per hour, you can use something like /var/lock/motionmail because there's just one per system.
If you want one email for each user per hour, you can use $HOME/.motionmail.lock because there's just one per user.
You can use /home/pi/send_email.py if you want with <, but this implies that you want one email per hour not only for each user, programming language and script copy, but also every time you hit save and replace the file with your editor*
* Editors differ in whether they replace or overwrite a file

Distributing payload to multiple cron jobs

I have a shell script say data.sh. For this script to execute I will pass a single argument say Table_1.
I have a test file which I will get as a result of a different script.
Now in a test file I have more than 1000 arguments to pass to the script.
The file looks like below:
Table_1
Table_2
Table_3
Table_4
and..so..on
Now I want to execute the script to run in parallel.
I am doing this using cron job.
First I am splitting the test file into 20 parts Using the split command in Linux.
split -l $(($(wc -l < test )/20 + 1)) test
I will then have the test file divided to 20 parts such as xaa,xab,xac and so on.
Then run the cron job:
* * * * * while IFS=',' read a;do /home/XXXX/data.sh $a;done < /home/xxxx/xaa
* * * * * while IFS=',' read a;do /home/XXXX/data.sh $a;done < /home/xxxx/xab
and so on.
As this involves lot of manual process. I would like to do this dynamically.
Here is what I want to achieve:
1) As soon as I get the test file I would like it to be split into say 20 files automatically and store at a particular place.
2) Then I would like to schedule the cron job for every day 5 Am by passing the 20 files as arguments to the script.
What is the best way to implement this? Any answers with explanation will be appreciated.
Here is what you could do. Create two cron jobs:
file_splitter.sh -> splits the file and stores them in a particular directory
file_processer.sh -> picks up one file at a time from the directory above, does a read loop, and calls data.sh. Removes the file after successful processing.
Schedule file_splitter.sh to run ahead of file_processor.sh.
If you want to achieve further parallelism, you can make file_splitter.sh write the split files into multiple directories with a few files in each. Let's say they are called sub1, sub2, etc. Then, you can schedule multiple instances of file_processor.sh and pass the sub directory name as an argument. Since the split files are stored in separate directories, we can ensure that only one job processes the files in a particular subdirectory.
It's better to keep the cron command as simple as possible.
* * * * * /path/to/file_processor.sh
is better than
* * * * * while IFS=',' read a;do /home/XXXX/data.sh $a;done < /home/xxxx/xab
Makes sense?
I had written a post about how to manage cron jobs effectively. You may want to take a look at it:
Managing log files created by cron jobs

Can you confirm my crontab line is right

I want to set a cron job to run at 00h15 every Friday. Is this the correct way to do this:
15 0 * * 5
Use this kind of website to validate your crons:
http://crontab.guru/#15_0___5

Cron Jobs Linux row deletion

I'm running this script;
$query = "SELECT * FROM XXX WHERE email='$Email'";
if($count==1) // fails
if($count==0) // succeeds
If successful
mysql_query ("INSERT INTO XXX (email) values ('$Email'");
Then proceeds onto the next script.
So, it checks to see if you have already ran this script in the past on that account, if you have your email is stored then you can't run this script ever again on that same email.
However, after this script has been processed I want it to delete the row created for the email after 6 hours.
So that after 6 hours they may run the script again.. I've been enlightened that I need to use Cron jobs for this, But I'm not sure how.. Any help is highly appreciated!
Many regards, and thanks in advance.
0 0,6,12,18 * * * /path/to/mycommand
This means starting from hour 0, 6, 12, and 18 the cron job would run. That would be the cron needed to do what you want.
Depending on which linux version you are running you will need to see how to actually create the cron job.
I would think at now +6 hours is a better choice here.

How to alter cron output e-mail for unique messages on Subject?

I have a cron job which runs every 4 hours. When it sends me e-mail in gmail.com of the output, it threads it and makes it hard to look at the most recent message or specific ones.
0 0,4,8,12,16,20 * * * /root/backup.sh #Backup of server
Would it be possible to have the Description field in a cron job insert the 'date' commands output so that it not only time stamps it in the Subject but makes it unique so the messages from the same cron job aren't threaded together?
Maybe something like this?
0 0,4,8,12,16,20 * * * /root/backup.sh #'Backup of server; date'
Thanks!
You could have a script which does not give any output to stderr or stdout itself (then cron won't send any email).
That script could send emails explicitly, e.g. using mail -s "some subject"; and you could also use logger to write log messages. You might want something like mail -s $(date +"backup %D")
Your crontab entry could redirect outputs, e.g. /root/betterbackup.sh > /dev/null 2>&1 and you explicitly ensure in betterbackup.sh that appropriate mails and logs are done.
You can use date +"%Y_%m_%d_%H:%M:%S" in the shell file where you are setting the description of the mail.
see this
If you want to specify date in your cron then you can try below syntax
0 */4 * * * yourshellscript.sh backup_server_`date +"%Y_%m_%d:%H:%M:%S"`
Remember if you are using mail -s "your subject" kind of mail sending then you have to escape doublequotes in the date command i mentioned above.
FYR see below
mail -s "backup_server_`date +\"%Y_%m_%d:%H:%M:%S\"`" ur_id#example.com < myfile.txt
Here myfile.txt contains the mail body.

Resources