根据变量的输出执行块

根据变量的输出执行块

下面是我起草的脚本,它将根据从中获取的 SID 来工作

 ps -ef | grep pmon

一旦 SID 被 grep 出来,它就会将 SID 传递给dbenv()设置必要的参数,并且还会从条目中删除 DB_VERSION /etc/oratab

根据版本,如果版本为 12 或 11,则脚本应执行一个块,或者如果版本为 10 或 9,则应执行一个块。

TRACE_FILE12 或 11 有s 值下的警报日志,10 或 9 不会有 的任何输出TRACE_FILE,因此 10 和 9 应根据BDUMPs 值清除警报日志。

所以我起草了下面的脚本,它工作得很好,我觉得该脚本有很多重复,其中我应用了 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-----------------------------------------------------------------------------------#

答案1

这个问题可能属于 https://codereview.stackexchange.com/而不是在这里,但这是我的建议:

  1. 使用$()而不是反引号进行命令替换。

  2. 你(几乎)永远不需要通过管道输入grepawk.例如,代替:

    ps -eaf | grep pmon | grep -v grep | awk '{print $8}'
    

    你可以做:

    ps -eaf | awk '/pmon/ && ! /grep/ {print $8}'
    

    同样,通常最好使用 进行管道grep传输。例如,而不是:cutawk

    cat /etc/oratab | grep ^$ORACLE_SID | cut -d":" -f2
    

    使用

    awk -F: "/^$ORACLE_SID/ {print \$2}" /etc/oratab
    

    (通常你不会在脚本中转义$of ,因为更常见的是单引号整个脚本。在这种情况下,我们双引号脚本,以便我们可以在 中使用 bash 变量,所以我们需要反斜杠转义是为了防止 shell 将其替换为自己的)$2awkawkawk$ORACLE_SIDawkawk$2$2

  3. 你不需要做管道ps进入grepawk无论如何。你也可以这样做ps h -o cmd -C pmon。或者使用pgrep.

  4. sed可以自己读取文件,不需要通过管道传输catsed.grepawkperl以及cut所有其他标准文本处理工具也可以。

  5. [ -n "$var" ]是相同的[ ! -z "$var" ]

    -z测试空字符串,-n测试非空字符串。

  6. 在某些情况下,您没有对变量进行双引号。当你使用变量时,你应该(几乎)总是用双引号引起来。

  7. 单引号用于固定的文字字符串。当您想要将变量或命令替换插入字符串时,可以使用双引号。

  8. 缩进 8 个字符过多。每个缩进级别使用 2 或 4 个空格。或者将编辑器中的制表位设置为 2 或 4 个空格。

  9. 使用小写或混合大小写作为自己的变量是一个好习惯,为标准实用程序和通用程序保留全部大写的变量名称。

  10. sqlplusmysql、等工具psql对于在 sh 或 bash 等中执行脚本化数据库查询非常方便,但是您必须非常小心与 SQL 命令一起使用的任何变量 - 特别是如果变量中的值来自用户提供的数据,或者其他“不可信”来源。如果输入数据未经验证且未经清理,则很容易破坏脚本。创建 SQL 注入错误同样容易。

    对于重要的 SQL 查询,您可能应该学习perlpython或其他带有支持占位符的数据库库的语言,以避免在 sql 命令中引用变量时出现任何问题。

相关内容