Abaixo está o script que esbocei, que funcionará com base nos SIDs que obterá
ps -ef | grep pmon
Depois que o SID for grepeado, ele passará o SID dbenv()
para definir os parâmetros necessários e também cortará o DB_VERSION das /etc/oratab
entradas.
Com base na versão, se 12 ou 11, o script deve executar um bloco ou, se a versão for 10 ou 9, deve executar um bloco.
12 ou 11 tem os logs de alerta sob TRACE_FILE
o valor de , 10 ou 9 não terá nenhuma saída para TRACE_FILE
, então 10 e 9 devem limpar o log de alerta com base no BDUMP
valor de s.
Então, esbocei o script abaixo e funciona bem, sinto que o script tem muita repetição onde apliquei a lógica para DB_VERSION.
Alguma ideia de como esse script poderia ser aprimorado
#############################################################################################################################################################
#!/bin/bash
#############################################################################################################################################################
TODAY=`date +%Y-%m-%d`
DATE=`date +%Y%b%d`
YESTERDAY=`date -d '-1 day' +%b%Y`
YDAY=`date -d '-1 day' +%Y%b%d`
HOST=`hostname`
LOG_LOCATION="/home/oracle/utility_script/dba_maint/logs"
mkdir -p ${LOG_LOCATION}
LOG_FILE="${LOG_LOCATION}/oracle_files_cleanup_${DATE}.log"
rm ${LOG_FILE} 2>/dev/null
dbenv ()
{
ORACLE_HOME=`cat /etc/oratab | grep ^$ORACLE_SID | cut -d":" -f2`; export ORACLE_HOME
PATH=$ORACLE_HOME/bin:$PATH ; export PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib ; export LD_LIBRARY_PATH
DB_VERSION=`cat /etc/oratab | grep "^$ORACLE_SID" | cut -d":" -f2 | rev | cut -d"/" -f2| rev | cut -d"." -f1`; export DB_VERSION
}
dbcheck()
{
sqlplus / as sysdba << EOF &>${LOG_LOCATION}/dbcheck.out
exit
EOF
}
sql_plus()
{
sqlplus -s / as sysdba << EOF &>/dev/null
SET NEWPAGE NONE;
set lines 200 pages 300;
set feedback off;
set heading off;
spool ${LOG_LOCATION}/$1.log
$2
exit
EOF
}
for SID in `ps -eaf | grep pmon | grep -v grep | awk '{print $8}' | sort | cut -d"_" -f3`
do
ORACLE_SID=${SID} ; export ORACLE_SID
dbenv ${ORACLE_SID} #-- Passing the ORACLE_SID to dbenv function to source the database.
if [ ${DB_VERSION} -eq 11 -o ${DB_VERSION} -eq 12 ]
then
dbcheck
DB_CHECK=`cat ${LOG_LOCATION}/dbcheck.out | egrep "ORA|SP2|idle"`
LOWER_SID=`echo ${ORACLE_SID} | tr '[A-Z]' '[a-z]'`
#-- Queries to fetch the proper log location from database
ADUMP="select DISPLAY_VALUE from v\$parameter where name='audit_file_dest';"
BDUMP="select DISPLAY_VALUE from v\$parameter where name='background_dump_dest';"
CDUMP="select DISPLAY_VALUE from v\$parameter where name='core_dump_dest';"
UDUMP="select DISPLAY_VALUE from v\$parameter where name='user_dump_dest';"
TRACE_FILE="select DISPLAY_VALUE from v\$parameter where name='diagnostic_dest';"
#-- Calls the sql_plus function with the parameters as the logname and SQL query
sql_plus "adump_${ORACLE_SID}" "${ADUMP}"
sql_plus "bdump_${ORACLE_SID}" "${BDUMP}"
sql_plus "cdump_${ORACLE_SID}" "${CDUMP}"
sql_plus "udump_${ORACLE_SID}" "${UDUMP}"
sql_plus "trace_${ORACLE_SID}" "${TRACE_FILE}"
#-- Remove any empty lines after the log location
ADUMP_LOC=`cat ${LOG_LOCATION}/adump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
BDUMP_LOC=`cat ${LOG_LOCATION}/bdump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
CDUMP_LOC=`cat ${LOG_LOCATION}/cdump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
UDUMP_LOC=`cat ${LOG_LOCATION}/udump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
TRACE_LOC=`cat ${LOG_LOCATION}/trace_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
#-- If the Database is not in idle state or without any errors, start housekeeping
if [ -z "${DB_CHECK}" ]
then
echo -e "\t\t\t\t HOUSEKEEPING for database : ${ORACLE_SID}" >>${LOG_FILE}
echo -e "\t\t\t\t ============ === ======== = =============" >>${LOG_FILE}
#-- Cleans .aud files older than 60 days in ADUMP location
if [ ! -z "${ADUMP_LOC}" ]
then
echo -e "\t\t\tAdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in BDUMP location
if [ ! -z "${BDUMP_LOC}" ]
then
echo -e "\n\n\t\t\tBdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in CDUMP location
if [ ! -z "${CDUMP_LOC}" ]
then
echo -e "\n\t\t\tCdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in UDUMP location
if [ ! -z "${UDUMP_LOC}" ]
then
echo -e "\n\t\t\tUdump cleanup" >> ${LOG_FILE}
fi
#-- Rotates the Database alert log on 01st of every month.
if [ `date +%d` -eq 01 ]
then
if [ ! -z "${TRACE_LOC}" ]
then
echo -e "\n\t\t\tALERT LOG ROTATION" >> ${LOG_FILE}
fi
fi
#-- Rotates the Listener log on 01st of every month.
if [ `date +%d` -eq 01 ]
if [ ! -z "${TRACE_LOC}" ]
then
echo -e "\n\t\t\tLISTENER LOG ROTATION" >> ${LOG_FILE}
fi
fi
else
echo -e "ERROR : Please fix the below error in database - ${ORACLE_SID} on host - ${HOST} \n ${DB_CHECK}" >> ${LOG_LOCATION}/house_keeping_fail_${ORACLE_SID}_${DATE}.log
fi
elif [ ${DB_VERSION} -eq 10 -o ${DB_VERSION} -eq 9 ]
then
dbcheck
DB_CHECK=`cat ${LOG_LOCATION}/dbcheck.out | egrep "ORA|SP2|idle"`
#-- Queries to fetch the proper log location from database
ADUMP="select DISPLAY_VALUE from v\$parameter where name='audit_file_dest';"
BDUMP="select DISPLAY_VALUE from v\$parameter where name='background_dump_dest';"
CDUMP="select DISPLAY_VALUE from v\$parameter where name='core_dump_dest';"
UDUMP="select DISPLAY_VALUE from v\$parameter where name='user_dump_dest';"
#-- Calls the sql_plus function with the parameters as the logname and SQL query
sql_plus "adump_${ORACLE_SID}" "${ADUMP}"
sql_plus "bdump_${ORACLE_SID}" "${BDUMP}"
sql_plus "cdump_${ORACLE_SID}" "${CDUMP}"
sql_plus "udump_${ORACLE_SID}" "${UDUMP}"
#-- Remove any empty lines after the log location
ADUMP_LOC=`cat ${LOG_LOCATION}/adump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
BDUMP_LOC=`cat ${LOG_LOCATION}/bdump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
CDUMP_LOC=`cat ${LOG_LOCATION}/cdump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
UDUMP_LOC=`cat ${LOG_LOCATION}/udump_${ORACLE_SID}.log | sed 's/[[:blank:]]*$//'`
#-- If the Database is not in idle state or without any errors, start housekeeping
if [ -z "${DB_CHECK}" ]
then
#-- Cleans .aud files older than 60 days in ADUMP location
if [ ! -z "${ADUMP_LOC}" ]
echo -e "\t\t\tAdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in BDUMP location
if [ ! -z "${BDUMP_LOC}" ]
then
echo -e "\n\n\t\t\tBdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in CDUMP location
if [ ! -z "${CDUMP_LOC}" ]
then
echo -e "\n\t\t\tCdump cleanup" >> ${LOG_FILE}
fi
#-- Cleans .trm or .trc files older than 60 days in UDUMP location
if [ ! -z "${UDUMP_LOC}" ]
then
echo -e "\n\t\t\tUdump cleanup" >> ${LOG_FILE}
fi
#-- Rotates the ${DB_VERSION} version Database alert log on 01st of every month.
if [ `date +%d` -eq 01 ]
then
if [ ! -z "${BDUMP_LOC}" ]
then
echo -e "\n\t\t\tALERT LOG ROTATION" >> ${LOG_FILE}
fi
fi
else
echo -e "ERROR : Please fix the below error in database - ${ORACLE_SID} on host - ${HOST} \n ${DB_CHECK}" >> ${LOG_LOCATION}/house_keeping_fail_${ORACLE_SID}_${DATE}.log
fi
fi
done
exit $?
#---------------------------------------------------------------------END-----------------------------------------------------------------------------------#
Esta questão provavelmente pertence a https://codereview.stackexchange.com/ em vez de aqui, mas aqui estão minhas recomendações:
use
$()
em vez de backticks para substituição de comando.você (quase) nunca precisa canalizar
grep
paraawk
. Por exemplo, em vez de:você pode fazer:
Da mesma forma, canalizar
grep
para dentrocut
geralmente é melhor feito comawk
. por exemplo, em vez de:usar
(normalmente você não escaparia do
$
of$2
em umawk
script porque é mais comum colocar aspas simples em todo oawk
script. Nesse caso, estamos colocando aspas duplas noawk
script para que possamos usar a variável bash$ORACLE_SID
emawk
, então precisamos barra invertida-escapeawk
para$2
evitar que o shell a substitua por sua própria$2
)você não precisa fazer pipe
ps
intogrep
ou deawk
qualquer maneira. Você pode apenas fazerps h -o cmd -C pmon
em vez disso. Ou usepgrep
.sed
pode ler arquivos por si só, você não precisa canalizarcat
parased
. Assimgrep
comoawk
eperl
ecut
e todas as outras ferramentas de processamento de texto padrão.[ -n "$var" ]
é o mesmo que[ ! -z "$var" ]
.-z
testa para string vazia,-n
testa para string não vazia.há várias ocasiões em que você não colocou aspas duplas em suas variáveis. você deve (quase) sempre colocar aspas duplas nas variáveis ao usá-las.
aspas simples são para strings literais fixas. aspas duplas são para quando você deseja interpolar uma variável ou substituição de comando em uma string.
recuar com 8 caracteres é excessivo. use 2 ou 4 espaços por nível de recuo. ou defina a parada de tabulação em seu editor para 2 ou 4 espaços.
é um bom hábito usar minúsculas ou MixedCase para suas próprias variáveis, deixando nomes de variáveis ALL CAPS para utilitários padrão e programas comuns.
ferramentas como
sqlplus
,mysql
,psql
, etc são muito convenientes para fazer consultas de banco de dados com script em sh ou bash etc, mas você deve ser extremamente cuidadoso com quaisquer variáveis que usar com comandos SQL - especialmente se os valores nas variáveis vierem de dados fornecidos pelo usuário ou outras fontes "não confiáveis". É muito fácil quebrar um script se os dados de entrada não forem validados e não sanitizados. É tão fácil criar um bug de injeção de SQL.Para consultas SQL não triviais, você provavelmente deve aprender
perl
oupython
alguma outra linguagem com uma biblioteca de banco de dados que suporte espaços reservados para evitar problemas com aspas de variáveis em comandos sql.