Execute um bloco baseado na saída de uma variável [closed]

0

Abaixo está o script que eu desenhei, que funcionará com base nos SIDs que ele obterá de

 ps -ef | grep pmon

Quando o SID for grep, ele passará o SID para dbenv() para definir os parâmetros necessários e também cortará o DB_VERSION das entradas /etc/oratab .

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 em TRACE_FILE , 10 ou 9 não terão saída para TRACE_FILE , então 10 e 9 devem limpar o log de alerta com base no valor BDUMP s.

Então eu desenhei o script abaixo e funciona bem, eu sinto que o script tem muita repetição onde eu apliquei a lógica para DB_VERSION.

Alguma idéia de como esse script pode 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-----------------------------------------------------------------------------------#
    
por sabarish jackson 23.02.2018 / 10:05

1 resposta

2

Esta questão provavelmente pertence a link em vez de aqui, mas aqui estão minhas recomendações:

  1. use $() em vez de backticks para substituição de comandos.

  2. você (quase) nunca precisa canalizar grep para awk . Por exemplo, em vez de:

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

    você pode fazer:

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

    Da mesma forma, canalizar grep para cut geralmente é melhor feito com awk . por exemplo, em vez de:

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

    use

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

    (normalmente você não escaparia do script $ of $2 em awk porque é mais comum citar o script awk inteiro. Nesse caso, estamos citando duas vezes awk script para que possamos usar a variável bash $ORACLE_SID em awk , portanto, precisamos fazer escape da barra invertida awk ' $2 para impedir que o shell a substitua por seu próprio $2 )

  3. você não precisa fazer o canal ps em grep ou awk mesmo assim. Você pode apenas fazer ps h -o cmd -C pmon . Ou use pgrep .

  4. sed pode ler arquivos por si só, você não precisa canalizar cat para sed . Então, pode grep e awk e perl e cut e todas as outras ferramentas de processamento de texto padrão.

  5. [ -n "$var" ] é o mesmo que [ ! -z "$var" ] .

    -z testes para string vazia, -n testes para string não vazia.

  6. existem várias ocasiões em que você não citou duas vezes suas variáveis. você deve (quase) sempre duplicar as variáveis ao usá-las.

  7. as aspas simples são para sequências literais fixas. aspas duplas são para quando você deseja interpolar uma variável ou substituição de comando em uma string.

  8. recuar com 8 caracteres é excessivo. use 2 ou 4 espaços por nível de recuo. ou defina a parada de tabulação no seu editor para 2 ou 4 espaços.

  9. é um bom hábito usar letras minúsculas ou MixedCase para suas próprias variáveis, deixando nomes de variáveis ALLCAPS para utilitários padrão e programas comuns.

  10. 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ê precisa ser extremamente cuidadoso com quaisquer variáveis que você usa com comandos SQL - especialmente se os valores nas variáveis são provenientes de dados fornecidos pelo usuário ou de outras fontes "não confiáveis". É muito fácil quebrar um script se os dados de entrada não forem validados e não forem analisados. É tão fácil criar um bug de injeção de SQL.

    Para consultas SQL não-triviais, você provavelmente deve aprender perl ou python ou algum outro idioma com uma biblioteca de banco de dados que suporte espaços reservados para evitar problemas com a cotação de variáveis em comandos sql.

por 23.02.2018 / 10:42