Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a script to check for errors and send a mail .when the script is executed manually, it works fine.. but when am addin it to the crontab it is not sending any mails.. crontab contents ..I want to run the script every morning at 10:22 am.. followin is the crontab content
When jobs run from cron, they do not have the same environment variables as you have with your interactive shell. For example, the PATH will be very limited. Make sure such a limited environment doe snot affect your program.
When jobs run from cron, they do not have the same environment variables as you have with your interactive shell. For example, the PATH will be very limited. Make sure such a limited environment doe snot affect your program.
Thanks mathew..I removed the environmental varible and I gave the path..but even then it is not executing..
No environmental variables are stored in the script..
Thanks
Yusuf
Script content :
*****************
#Script used to monitor the database alert log file
#LOGFILE=/tmp/database_alert_$ORACLE_SID.log
RETURN_CODE=`grep ORA-* /d02/oracle/oracrp/proddb/9.2.0/admin/DEV_oracle/bdump/alert_DEV.log | wc -l`
if [ $RETURN_CODE -eq 0 ]
then
exit 0
else
echo "DEV - There are $RETURN_CODE errors in Alert log" | /usr/sbin/sendmail -v erp_webmail@ali.com.kw
$LOGFILE
exit 1
fi
I think the parameter to grep should be simplified. There is no need for the * character at all, and it is risky.
Firstly, the regular expression ORA-* will match all of the following:
ORA-
ORA--
ORA---
ORA----
* in the context of a regular expression (which is what grep expects as it's first argument) means "the previous expression atom repeated 0 or more times". The previous atom in this case being the hyphen character.
Moreover, having an un-quoted * as the first argument to grep is dangerous. If the working directory of the program contains any files matching the glob pattern ORA-* the shell will replace that argument with the list of matching file names, which could lead to unexpected behaviour (since it is not possible to predict what files will ever exist in this directory).
Because of the first point about pattern being meaningless, just omit the *. If you really did want a * in the pattern (e.g. if the pattern were ORA-[0-9]* meaning to match ORA- followed by 0 or more digits), you should quote the pattern. Single quotes - not to be confused with backticks - prevent the shell from interpretting anything, and are the best choice here.
The line $LOGFILE is meaningless, especially given than you have commented out the definition of the variable.
The use of the -v option to sendmail doesn't make ant sense. It means that the next argument is the envelope ID. You should omit this I think.
Lastly, and perhaps most importantly, there is no shabang line for your script. How are you invoking this on the command line (i.e. when you don't run it from cron)? If you are doing something like this:
Code:
. your_script_filename
or
Code:
source your_script_filename
...then that is the reason. Scripts which are invoked using the . or source commands are executed in the current shell. If you try to invoke these files as programs (i.e. by specifying there path and expecting the OS to treat them as an executable), you need to do two things:
Add a shabang line at the top of the script. This must be the first line of the script file, and there must be no space before the # character:
Code:
#!/bin/sh
You must also make the program executable, by setting the mode (permissions) of the file. You do this with the chmod command, probably like this:
Code:
chmod 755 your_script_filename
So here is how I would change the script:
Code:
#!/bin/sh
# Script used to monitor the database alert log file
# LOGFILE=/tmp/database_alert_$ORACLE_SID.log
RETURN_CODE=`grep ORA- /d02/oracle/oracrp/proddb/9.2.0/admin/DEV_oracle/bdump/alert_DEV.log | wc -l`
if [ $RETURN_CODE -eq 0 ]
then
exit 0
else
echo "DEV - There are $RETURN_CODE errors in Alert log" | /usr/sbin/sendmail erp_webmail@ali.com.kw
# what is this for? $LOGFILE
exit 1
fi
There is nothing in this script to generate the log which is mentioned, but at least the notification should be sent.
If you want to generate the log you are in trouble. The ORACLE_SID value is taken from the environment - which you do not get when running from cron. You will need to either choose a different log file name, or find some way to determine this value without getting it from the environment.
Last edited by matthewg42; 12-03-2007 at 07:33 AM.
Reason: typo
I think the parameter to grep should be simplified. There is no need for the * character at all, and it is risky.
Firstly, the regular expression ORA-* will match all of the following:
ORA-
ORA--
ORA---
ORA----
* in the context of a regular expression (which is what grep expects as it's first argument) means "the previous expression atom repeated 0 or more times". The previous atom in this case being the hyphen character.
Moreover, having an un-quoted * as the first argument to grep is dangerous. If the working directory of the program contains any files matching the glob pattern ORA-* the shell will replace that argument with the list of matching file names, which could lead to unexpected behaviour (since it is not possible to predict what files will ever exist in this directory).
Because of the first point about pattern being meaningless, just omit the *. If you really did want a * in the pattern (e.g. if the pattern were ORA-[0-9]* meaning to match ORA- followed by 0 or more digits), you should quote the pattern. Single quotes - not to be confused with backticks - prevent the shell from interpretting anything, and are the best choice here.
The line $LOGFILE is meaningless, especially given than you have commented out the definition of the variable.
The use of the -v option to sendmail doesn't make ant sense. It means that the next argument is the envelope ID. You should omit this I think.
Lastly, and perhaps most importantly, there is no shabang line for your script. How are you invoking this on the command line (i.e. when you don't run it from cron)? If you are doing something like this:
Code:
. your_script_filename
or
Code:
source your_script_filename
...then that is the reason. Scripts which are invoked using the . or source commands are executed in the current shell. If you try to invoke these files as programs (i.e. by specifying there path and expecting the OS to treat them as an executable), you need to do two things:
Add a shabang line at the top of the script. This must be the first line of the script file, and there must be no space before the # character:
Code:
#!/bin/sh
You must also make the program executable, by setting the mode (permissions) of the file. You do this with the chmod command, probably like this:
Code:
chmod 755 your_script_filename
So here is how I would change the script:
Code:
#!/bin/sh
# Script used to monitor the database alert log file
# LOGFILE=/tmp/database_alert_$ORACLE_SID.log
RETURN_CODE=`grep ORA- /d02/oracle/oracrp/proddb/9.2.0/admin/DEV_oracle/bdump/alert_DEV.log | wc -l`
if [ $RETURN_CODE -eq 0 ]
then
exit 0
else
echo "DEV - There are $RETURN_CODE errors in Alert log" | /usr/sbin/sendmail erp_webmail@ali.com.kw
# what is this for? $LOGFILE
exit 1
fi
There is nothing in this script to generate the log which is mentioned, but at least the notification should be sent.
If you want to generate the log you are in trouble. The ORACLE_SID value is taken from the environment - which you do not get when running from cron. You will need to either choose a different log file name, or find some way to determine this value without getting it from the environment.
Thanks mathew for your patience and answer.. that really helped me..
but am afraid still I can run the script normally using sh script.sh which sends the mail and when I put it in crontab it is not working the expected way..
Thanks mathew for your patience and answer.. that really helped me..
but am afraid still I can run the script normally using sh script.sh which sends the mail and when I put it in crontab it is not working the expected way..
Please guide
Yusuf
Do not run it with "sh script.sh". This runs the program in the current shell, and this it not what cron does. Cron tried to execute it as an executable, and for that you must chmod it and add the shabang as I described above.
Assuming the script is called script.sh, please execute these commands from the directory where the file exists and paste the output here (use [code] tags to help readability):
Code:
ls -l script.sh
head -n 1 script.sh
mount |grep " $(df . |tail -n 1 |awk '{ print $NF }') "
ls -l /bin/sh
Do not run it with "sh script.sh". This runs the program in the current shell, and this it not what cron does. Cron tried to execute it as an executable, and for that you must chmod it and add the shabang as I described above.
Assuming the script is called script.sh, please execute these commands from the directory where the file exists and paste the output here (use [code] tags to help readability):
Code:
ls -l script.sh
head -n 1 script.sh
mount |grep " $(df . |tail -n 1 |awk '{ print $NF }') "
ls -l /bin/sh
Thanks mathew.. here what u asked
[oracrp@oracle test]$ ls -l alert.sh
-rwxrwxrwx 1 oracrp dba 409 Dec 3 16:55 alert.sh
[oracrp@oracle test]$ head -n 1 alert.sh
#!/bin/sh
[oracrp@oracle test]$ mount |grep " $(df . |tail -n 1 |awk '{ print $NF }') "
/dev/cciss/c0d0p1 on / type ext3 (rw)
[oracrp@oracle test]$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 May 24 2007 /bin/sh -> bash
[oracrp@oracle test]$ ls -l alert.sh
-rwxrwxrwx 1 oracrp dba 409 Dec 3 16:55 alert.sh
[oracrp@oracle test]$ head -n 1 alert.sh
#!/bin/sh
[oracrp@oracle test]$ mount |grep " $(df . |tail -n 1 |awk '{ print $NF }') "
/dev/cciss/c0d0p1 on / type ext3 (rw)
[oracrp@oracle test]$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 May 24 2007 /bin/sh -> bash
Waiting on u ..
Thanks
Yusuf
You didn't use [code] tags, but nevermind.
Hmm, well everything looks in order there. Just by was of explanation.. the mount mount command was to see if the drive where the file exists is mounted in a way which prevents running of scripts.
Hmm, well everything looks in order there. Just by was of explanation.. the mount mount command was to see if the drive where the file exists is mounted in a way which prevents running of scripts.
What happens when you run the script like this:
Code:
./alert.sh
(from the directory where the file is)...?
Thanks mathew,
if I give the command like ./alert.sh
it executes and sends the mail..
Well it's very odd that it doesn't when it executes from cron. The next thing I would do is to verify that cron is executing anything. I would do this by temporarily moving the script, and creating another which will just put a timestamp in a file, which you can check:
Then wait for the cron job to execute and check that the file /tmp/my_alert_test.log has been created and has the expected date and time in it.
This will verify that your crontab is being executed, and that you have edited it correctly. Incidentally, what is in your crontab?
One last thing... The permissions on the alert.sh which you have set are very bad indeed. This file is writable by any user or process on the system. This is extremely bad security, even if you think you are the only user on the machine. Don't do it. If you don't understand permissions properly, you should stop now and go read up on them. This is very important.
Well it's very odd that it doesn't when it executes from cron. The next thing I would do is to verify that cron is executing anything. I would do this by temporarily moving the script, and creating another which will just put a timestamp in a file, which you can check:
Then wait for the cron job to execute and check that the file /tmp/my_alert_test.log has been created and has the expected date and time in it.
This will verify that your crontab is being executed, and that you have edited it correctly. Incidentally, what is in your crontab?
One last thing... The permissions on the alert.sh which you have set are very bad indeed. This file is writable by any user or process on the system. This is extremely bad security, even if you think you are the only user on the machine. Don't do it. If you don't understand permissions properly, you should stop now and go read up on them. This is very important.
Well it looks like your cron job is not executing at all. Perhaps the user oracrp is not allowed to run cron jobs, or maybe the cron daemon is not running at all?
Well it looks like your cron job is not executing at all. Perhaps the user oracrp is not allowed to run cron jobs, or maybe the cron daemon is not running at all?
Mathew,
Cron is working fine.. I tried creating a sample file with the cron and it created.. the problem with that it is not sending the mails.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.