下面是我起草的脚本,它将根据它将从中获得的 SID 工作
ps -ef | grep pmon
一旦 SID 被 grepped,它将传递 SID 以设置必要的参数,并且它还会从条目dbenv()
中删除 DB_VERSION 。/etc/oratab
根据版本,如果是 12 或 11,那么脚本应该执行一个块,或者如果版本是 10 或 9,它应该执行一个块。
12 或 11 的警报日志在TRACE_FILE
' 值下,10 或 9 不会有任何输出TRACE_FILE
,因此 10 和 9 应根据BDUMP
s 值清除警报日志。
所以我起草了下面的脚本,它工作正常,我觉得脚本有很多重复,我为 DB_VERSION 应用了逻辑。
关于如何增强此脚本的任何想法
#############################################################################################################################################################
#!/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-----------------------------------------------------------------------------------#
这个问题可能属于 https://codereview.stackexchange.com/而不是这里,但这是我的建议:
使用
$()
而不是反引号进行命令替换。您(几乎)永远不需要
grep
输入awk
. 例如,而不是:你可以做:
grep
类似地,管道cut
通常最好使用awk
. 例如,而不是:利用
(通常你不会在脚本中转义
$
of ,因为更常见的是单引号整个脚本。在这种情况下,我们双引号脚本,以便我们可以使用 bash 变量,所以我们需要反斜杠转义,以防止外壳用自己的替换它)$2
awk
awk
awk
$ORACLE_SID
awk
awk
$2
$2
你不需要做管道
ps
或grep
无论如何awk
。你可以这样做ps h -o cmd -C pmon
。或使用pgrep
.sed
可以自己读取文件,你不需要管道cat
到sed
. 其他标准文本处理工具也grep
可以。awk
perl
cut
[ -n "$var" ]
是一样的[ ! -z "$var" ]
。-z
测试空字符串,-n
测试非空字符串。有几次你没有双引号你的变量。当你使用它们时,你应该(几乎)总是用双引号引起来。
单引号用于固定的文字字符串。双引号用于将变量或命令替换插入字符串时。
缩进 8 个字符是多余的。每个缩进级别使用 2 或 4 个空格。或将编辑器中的制表位设置为 2 或 4 个空格。
对您自己的变量使用小写或 MixedCase 是一个好习惯,而将 ALLCAPS 变量名留给标准实用程序和常用程序。
sqlplus
,mysql
,等工具psql
对于在 sh 或 bash 等中执行脚本数据库查询非常方便,但您必须非常小心使用 SQL 命令的任何变量 - 特别是如果变量中的值来自用户提供的数据,或者其他“不受信任”的来源。如果输入数据未经验证和未经处理,很容易破坏脚本。创建 SQL 注入错误同样容易。对于非平凡的 SQL 查询,您可能应该学习
perl
或python
使用支持占位符的数据库库的其他语言,以避免在 sql 命令中引用变量时出现任何问题。