Lspatches
Lspatches
/bin/bash
# 20190906 - Fred Denis - A new -V option to show the version of the script
# 20191401 - Fred Denis - opatchauto report: show Homes with -s option properly, fixed
GREP/UNGREP
# 20190401 - Fred Denis - Implement opatchauto report instead of lsinventory -all_nodes for
versions > 1220112 or for 11g
# 20180704 - Fred Denis - GREP and UNGREP now works when a file is specified
# 20180626 - Fred Denis - Started the opatch version management by showing a warning when the
special 12.2.0.1.13 and 11.2.0.3.18 versions are used
# see https://unknowndba.blogspot.com/2018/06/deprecation-of-opatch-
command-option.html for more information
# Shows an error when opatch raises an error (when another user owns the
ORACLE_HOME for example)
# 20180625 - Fred Denis - Different OS support : (the script is developed under Linux)
# --- Solaris :
# - grep "^[Aa-Zz|+]" does not work on Solaris so I moved to grep -v "^#" | grep -v
"^$" when reading oratab
# - default Solaris awk is the original awk and nawk lacks features from gawk (the
script definitely does not work with nawk due to array management features)
# gawk is installed by default with Solaris 11 and is available for Solaris < 11, the
script then expects gawk to be here for Solaris and if not it cannot continue
# - The "case" to support other OS is also HP-UX and AIX ready but I have not tested it
as I have no such OS handy
# Default values
TMP=/tmp/fictemplspatches$$ # A tempfile
show_version()
# An usage function
usage()
END
END
$0 relies on the content of the /etc/oratab file to look at the installed patch on the
ORACLE_HOMEs
It uses the opatch installed on each Home to list the installed patches and find the missing
ones in case of RAC system
A file containing some opatch outputs can also be provided to $0; it will then not use opatch
but rely on the input file
If olsnodes from the ASM Home returns no rows then we go with local opatch
END
-o An output file if you just want to generate the opatch output (no patch analysis shown)
-l Run opatch as Local only (default is opatch is run using the -all_nodes option)
-g Act as a grep command to grep the Homes you want to have the patches information
Examples :
-v Act as a grep -v comnmand when selecting the Homes you want the patches information
from; it can be combined with the -g option
Examples :
-s Show the ORACLE_HOMEs that would be considered by the script, it can be used in
conjunction with the -g and -v options
You can then test your -g and -v combination here
Examples :
END
exit 123
# Parameters management
case ${OPT} in
f) FILE=${OPTARG} ;;
o) OUT=${OPTARG} ;;
g) GREP=${OPTARG} ;;
l) ALL_NODES="" ;;
v) UNGREP=${OPTARG} ;;
s) SHOW_HOMES="YES" ;;
h) usage ;;
esac
done
#
# Different OS support
OS=`uname`
case ${OS} in
SunOS)
ORATAB=/var/opt/oracle/oratab
AWK=/usr/bin/gawk ;;
Linux)
ORATAB=/etc/oratab
AWK=`which awk` ;;
HP-UX)
ORATAB=/etc/oratab
AWK=`which awk` ;;
AIX)
ORATAB=/etc/oratab
AWK=`which awk` ;;
exit 666 ;;
esac
if [ ! -f ${ORATAB} ]
then
cat << !
!
exit 667
fi
if [ ! -f ${AWK} ]
then
cat << !
exit 668
fi
then
$0 -h for help
END
exit 669
fi
if [ ${SHOW_HOMES} = "YES" ]
then
if [[ -f ${FILE} ]]
then
cat ${FILE} | grep "^Oracle Home" | awk 'BEGIN {FS=":"} { printf("\t%s\n", $NF)}' |
grep ${GREP} | grep -v ${UNGREP} | sort | uniq
cat ${FILE} | grep "homes path=" | uniq | sed s'/" .*$//' | sed s'/.*"//' | sort | grep $
{GREP} | grep -v ${UNGREP}
else
cat ${ORATAB} | grep -v "^#" | grep -v "^$" | grep -v agent | awk 'BEGIN {FS=":"}
{ printf("\t%s\n", $2)}' | grep ${GREP} | grep -v ${UNGREP} | sort | uniq
fi
printf "\n"
exit 0
fi
if [ ! -f ${FILE} ]
then
cat << !
exit 123
fi
if [[ -n ${OUT} ]]
then
if [ -d ${OUT} ]; then echo "${OUT} is a directory, please specify a regular file; cannot
continue."; exit 670; fi
if [ ! -w `dirname ${OUT}` ] ; then echo "`dirname ${OUT}` is not writable; cannot continue.";
exit 671; fi
fi
# Set the ASM env to be able to use crsctl commands as well as olsnodes
ORACLE_SID=`ps -ef | grep pmon | grep asm | awk '{print $NF}' | sed s'/asm_pmon_//' | egrep
"^[+]"`
if [ -z ${ORACLE_SID} ]
then
ALL_NODES=""
else
export ORAENV_ASK=NO
if [ ! -f ${ORACLE_HOME}/bin/olsnodes ]
then
ALL_NODES=""
else
then
ALL_NODES=""
fi
fi
fi
then
for OH in `cat ${ORATAB} | grep -v "^#" | grep -v "^$" | grep -v agent | awk 'BEGIN {FS=":"}
{ print $2}' | grep ${GREP} | grep -v ${UNGREP} | sort | uniq`
do
then
ERR=$?
if [ ${ERR} -eq 0 ]
then
then # remote
if [ "${ALL_NODES}" = "Yes" ]
then
else
ALL_NODES_OPTION=""
fi
ERR=$?
else # lsinventory
if [ "${ALL_NODES}" = "Yes" ]
then
else
ALL_NODES_OPTION=""
fi
ERR=$?
fi
if [ ${ERR} -eq 0 ]
then
else
cat ${TMP2} ;
fi
else
fi
#if (((substr(OPATCH_VERSION_NUMERIC,1,2) == 12) &&
(OPATCH_VERSION_NUMERIC > 1220112)) ||
#ERR=$?
#then
#else
# cat ${TMP2} ;
#fi
fi
done
else
cp ${FILE} ${TMP}
fi
#echo $TMP
#exit
# An output file is specified, we just want the opatch output so we exit before analyzing the opatch
output
#
if [[ -n ${OUT} ]]
then
if [ -f ${TMP} ]
then
cp ${TMP} ${OUT}
if [ $? -ne 0 ]
then
Could not copy the tempfile into ${OUT}; the opatch output should be in ${TMP};
END
fi
rm -f ${TMP}
exit $?
fi
fi
printf "\n" ;
'BEGIN { FS = ":" ;
# some colors
COLOR_BEGIN = "\033[1;" ;
COLOR_END = "\033[m" ;
RED = "31m" ;
GREEN = "32m" ;
YELLOW = "33m" ;
BLUE = "34m" ;
TEAL = "36m" ;
WHITE = "37m" ;
COL_NODE = 16 ;
COL_PATCH = 12 ;
COL_VER = 14 ;
return sprintf(COLOR_BEGIN color "%" left "s%s%" right "s" COLOR_END sep, "", str, "" )
;
function print_a_line()
function print_output()
WIDTH = COL_PATCH+COL_NODE*n+n+1 ;
if (OPATCH_VERSION == "")
# A header
print_a_line() ;
printf("\n") ;
print_a_line() ;
some_patches=0 ;
p=asort(all_patches) ;
some_patches=1 ;
printf "\n" ;
if (some_patches == 0)
delete all_patches ;
delete patch_tab ;
delete nodes ;
delete descr ;
NB_PATCHES_INSTALLED=0 ;
print_a_line() ;
printf "\n" ;
# Main awk
#
{ if ($0 ~ /^Oracle Interim Patch Installer version/)
OPATCH_VERSION=$0 ;
OPATCH_VERSION_NUMERIC=$0 ;
OH=$2 ;
oh_tab[oh_nb++]=OH ;
next ;
while (getline)
SERVER = $2 ;
nodes[1] = $2 ;
n=1 ;
{
cpt=1 ;
while(getline)
{ if ($0 ~ /^$/)
{ break ;
nodes[cpt] = $0 ;
cpt++ ;
nodes_list = "" ;
while(getline)
if ($0 ~ /^$/)
break ;
if ($1 ~ /^ *[0-9]* /)
if (nodes_list == "")
{ nodes_list = $1 ;
} else {
nodes_list=nodes_list","$1 ;
SERVER=$2 ;
NB_PATCHES_INSTALLED = $1 ;
NB_PATCHES_FOUND = 0 ;
while(getline)
{ NB_PATCHES_FOUND++ ;
patch_id = $1 ;
if (patch_id in all_patches)
{ cpt++; } else {
getline; getline ;
descr[patch_id] = $0 ;
if (NB_PATCHES_FOUND == NB_PATCHES_INSTALLED)
{ break ;
print_output() ;
break ;
while (getline)
SERVER=$0 ;
n++ ;
nodes[n]=SERVER ;
OH=$0 ;
next ;
patch_id = $0 ;
if (patch_id in all_patches)
{ cpt++; } else {
}
}
{ print_output() ;
break ;
} ' ${TMP}
do
if [ -f ${F} ]
then
rm -f ${F}
fi
done
#************************************************************************#
#* END OF SOURCE *#
#************************************************************************#