Linux - EnterpriseThis forum is for all items relating to using Linux in the Enterprise.
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 am pretty new at creating/configuring cron jobs, so please excuse any glaring errors in my terminology or setup. The distro/version of Linux I am running is Oracle Linux Server release 6.3.
I have three shell scripts which need to be executed each evening, 5 minutes apart (to export three separate Oracle databases).
I can execute the scripts manually, and they work perfectly. For example:
Code:
$ sh ./expdp_caldev.sh
So I added three entries to crontab for the oracle user:
1. show the scripts.
More to the point, the default env in cron is minimal/unreliable. ALWAYS use full absolute paths to cmds and files used, or start by sourcing a file that sets up the correct env.
Incidentally, if want to use bash, say bash and not sh; they aren't necessarily the same.
On my system I'd use
Code:
#!/bin/bash
as the first line of each script, in which case no need for external call to bash (or sh )
Note that if cron has a problem it normally emails the cron owner or root
2. owner: given you are backing up an ora db, I'd normally expect oracle to have sufficient privs, but you might need to use root's crontab if it needs extra privs.
Here is one of the scripts that needs to get executed. The three scripts are all identical except for the Oracle SID and usernames/passwords.
Code:
#!/bin/bash
# set the environment
export ORACLE_HOME=/opt/oracle/oracle/product/11.2.0/dbhome_1
export ORACLE_BASE=/opt/oracle/oracle
export ORACLE_SID=******
export DMPDIR=/usr/oracle/export
export EXPORT_DIR_NAME=export
export DUMP_FILE=expdp_${ORACLE_SID}.dmp
export LOG_FILE=expdp_${ORACLE_SID}.log
export SYSTEM_USER=system
export SYSTEM_PASSWD=******
export DB_SYSTEM_USER_PASS=${SYSTEM_USER}/${SYSTEM_PASSWD}@${ORACLE_SID}
export INTERNAL_USER=******
export REPORT_USER=******
# change to the working directory
cd ${DMPDIR}
# check for existing logfile and
# remove if found.
#echo Removing log file
if [ -e ${DMPDIR}/${LOG_FILE} ]; then
rm ${DMPDIR}/${LOG_FILE}
fi
# check for existing dump file and
# remove if found.
#echo Removing old dump file
if [ -e ${DMPDIR}/${DUMP_FILE} ]; then
rm ${DMPDIR}/${DUMP_FILE}
fi
# call expdp to export DB
expdp ${DB_SYSTEM_USER_PASS} directory=${EXPORT_DIR_NAME} dumpfile=${DUMP_FILE} schemas=${INTERNAL_USER},${REPORT_USER} exclude=statistics logfile=${LOG_FILE}
# Get the log status for email.
export STATUS=`grep Job ${DMPDIR}/${LOG_FILE}`
# mail results.
mailx -s "DB Export Log: ${ORACLE_SID} - ${STATUS}" ******@******.com < ${DMPDIR}/${LOG_FILE}
# rename the log file to preserve it.
if [ -e ${DMPDIR}/${LOG_FILE} ]; then
mv ${DMPDIR}/${LOG_FILE} ${DMPDIR}/${LOG_FILE}.`date +%y%m%d`
fi
Is there anything in the script which screams "you idiot, what are you doing?" When I run the script manually, it works perfectly - the DB is exported; I get the email with the log results; and the log file is renamed with the date stamp. I execute the script manually as the oracle user.
Regarding bash vs sh, I am not enough of a Linux person to really understand the difference (I'll have to consult Dr Google to find out).
Is there anything in the script which screams "you idiot, what are you doing?"
No, more like "why aren't you listening?" as chrism01 said you should export the full path. Taking shell scripting basics and linosaurusroot' suggestion into account here is a rewritten version (one script to rule all them databases) exporting PATH, allowing for per-SID credentials, checking if binaries are found, etc, etc:
Code:
#!/bin/bash --
# Set debug mode while testing:
set -vx
# Process all SIDs:
for CURRENT_SID in orc1 orc2 orc3; do
export ORACLE_SID="${CURRENT_SID}"
# Set per-SID credentials below:
case $ORACLE_SID in
orc1) export SYSTEM_PASSWD=******; export INTERNAL_USER=******; export REPORT_USER=******
;;
orc2) export SYSTEM_PASSWD=******; export INTERNAL_USER=******; export REPORT_USER=******
;;
orc3) export SYSTEM_PASSWD=******; export INTERNAL_USER=******; export REPORT_USER=******
;;
esac
# Fill the rest of the environment
export PATH=$PATH:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/oracle/bin:/home/oracle/app/product/11.2.0/bin:/opt/oracle/bin:/opt/oracle/oracle/product/11.2.0/bin
export ORACLE_HOME="/opt/oracle/oracle/product/11.2.0/dbhome_1"
export ORACLE_BASE="/opt/oracle/oracle"
export DMPDIR="/usr/oracle/export"
export EXPORT_DIR_NAME="export"
export DUMP_FILE="expdp_${ORACLE_SID}.dmp"
export LOG_FILE="expdp_${ORACLE_SID}.log"
export SYSTEM_USER="system"
export DB_SYSTEM_USER_PASS="${SYSTEM_USER}/${SYSTEM_PASSWD}@${ORACLE_SID}"
# Pre-flight check if we can find stuff in current path:
for BINARY in expdp mailx; do
which $BINARY >/dev/null 2>&1 || { echo "Cant find "$BINARY" in PATH=\"${PATH}\", exiting."; exit 1; }
done
# Pre-flight check CWD and move items:
cd ${DMPDIR} || { echo "Cant cd, exiting."; exit 1; }
for ITEM in "${LOG_FILE}" "${DUMP_FILE}"; do
[ -f "${DMPDIR}/${ITEM}" ] && rm -f "${DMPDIR}/${ITEM}" || { echo "Epic fail removing "${ITEM}", exiting."; exit 1; }
done
# Now call expdp to export current DB
expdp "${DB_SYSTEM_USER_PASS}" directory="${EXPORT_DIR_NAME}" dumpfile="${DUMP_FILE}" schemas="${INTERNAL_USER},${REPORT_USER}" exclude=statistics logfile="${LOG_FILE}"
[ $? -ne 0 ] && { echo "Error while processing SID: ${CURRENT_SID}."; }
# Get the log status for email.
export STATUS=$(grep -m1 Job "${DMPDIR}/${LOG_FILE}")
# mail results.
mailx -s "DB Export Log: ${ORACLE_SID} - ${STATUS}" ******@******.com < "${DMPDIR}/${LOG_FILE}"
# rename the log file to preserve it.
[ -f ${DMPDIR}/${LOG_FILE} ] && mv -f $"{DMPDIR}/${LOG_FILE}" "${DMPDIR}/${LOG_FILE}.$(/bin/date +'%Y%m%d')"
# Ready to process next SID now.
done
# All done, exit nicely.
exit 0
As always YMMV(VM) so change the exported PATH to include the directories you use and test it on a non-production database first.
My apologies - I thought chrism01 meant to export the full paths to whatever commands or files I was referencing; I didn't realise chrism01 meant to export the PATH variable.
Many thanks for re-writing the shell script - I really appreciate it. Just reading through it has taught me some neat tricks I didn't know which I'm sure will come in handy one day.
I note that you've added the line
Code:
set -vx
which was what chrism01 also recommended. I gather this will generate a log file - where will the log be created? In the same folder as the script?
No need to apologize. If you run the script manually it'll output to stdout. If you run the script as cron job then it'll be emailed to the cron job owner or whomever the non-empty MAILTO cron job variable is set to. Next to testing it on a non-production database it may be beneficial to run the script from the CLI first.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.