SQLPlus from shell
This is my first script calling Oracle SQLPlus.
- The /nolog option takes care of hiding the password from ps and similar tools.
- The command line will be 'sqlplus -S user/password@host:port/SID' without /nolog.
- The line 'host sleep 60' can be used in the script to delay execution.
- The 'set' parameters can be grouped together.
- sqlplus should use encrypted connection
- Make sure the script itself is not readable by unauthorized people.
- The script is written in AIX ksh.
Some details were changed, the blocks are part of a working script. You are right if you think there are better ways for handling certain conditions, the script is being improved.
There are some Oracle variables required for sqlplus.
NLS_LANG=<optional>
ORA_NLS33=<optional>
ORACLE_BASE=<set either this or ORACLE_HOME>
ORACLE_HOME=<>
PATH=$PATH:<path to sqlplus>
TNS_ADMIN=
export NLS_LANG ORA_NLS33 ORACLE_BASE ORACLE_HOME PATH TNS_ADMIN
As an example, we query an update timestamp from the DB, here, the time when a currency rate was updated.
Unfortunately, I'm still getting a blank line after each select result, so I must handle that later.
query_someapp1_update() {
sqlplus -S /nolog <<EOF
connect someapp1/password@host:port/SID;
set echo off;
set heading off;
set newpage none;
set pagesize 0;
-- select distinct value1 from table1 where field1 = 'F1' and curr = 'EUR=';
select distinct value2 from table1 where field1 = 'F2' and curr = 'EUR=';
-- select to_char (sysdate,'DD MON YYYY') from dual;
select to_char (sysdate - 1/24,'HH24:MI') from dual;
EOF
}
Query someapp2's status
query_someapp2_status() {
sqlplus -S /nolog <<EOF
connect someapp2/password@host:port/SID;
set echo off;
set heading off;
set newpage none;
set pagesize 0;
select status from sometable;
EOF
}
This function will restart our standalone Java app, "someapp1" if the timestamp shows a defined delay.
restart_someapp1 () {
if [ $(expr "$systemtime_in_mins" - "$APPLtime_in_mins") -ge "$allowed_diff" ]; then
echo "$(date +%F-%T) [INFO ] Restarting"
kill -9 $(ps -u someapp1 -o pid,comm | awk '/java/ {print $1}')
su - someapp1 -c ~/someapp1/start_someapp1.sh
else
echo "$(date +%F-%T) [INFO ] someapp1 check OK"
fi
}
Check if someapp2 should be open
check_status() {
if [ $(date +%H%M) -ge 1700 ] || [ $(date +%H%M) -le 0800 ]; then
# someapp2 is closed, not checking
continue
elif [ $(query_someapp2_open | xargs echo) -ne 1 ]; then
echo "$(date +%F-%T) [ERROR] someapp2 should be open, but it is closed."
else
echo "$(date +%F-%T) [INFO ] someapp2 check OK"
fi
}
The main part of the script. xargs comes in the picture, as I need the results on a single line. NB: whitespace is not handled here!
## Query the someapp1 update and the system time from the DB, join the result on a single line, store the result in an array
set -A times $(query_someapp1_update | xargs echo | sed 's/\:/ /g')
## Do nothing right after 00:00 to the amount of allowed time difference to avoid messing around with numbers
if [ "${times[2]}""${times[3]}" -lt "$allowed_diff" ]; then
# This should evaluate to something like '0008 is less than 10'
exit 0
fi
## Convert hours to minutes
someapp1_time_in_mins=$(expr "${times[0]}" \* 60 + "${times[1]}")
systemtime_in_mins=$(expr "${times[2]}" \* 60 + "${times[3]}")
Then comes the actual execution of the functions.