변수의 출력을 기반으로 블록 실행 [닫기]

변수의 출력을 기반으로 블록 실행 [닫기]

다음은 내가 작성한 SID를 기반으로 작동하는 스크립트입니다.

 ps -ef | grep pmon

SID가 grep되면 SID를 전달하여 dbenv()필요한 매개변수를 설정하고 항목에서 DB_VERSION도 제거합니다 /etc/oratab.

버전에 따라 스크립트는 버전이 12 또는 11인 경우 블록을 실행하고 버전이 10 또는 9인 경우 블록을 실행해야 합니다.

TRACE_FILE12 또는 11에는 s 값 아래의 경고 로그가 있고, 10 또는 9에는 출력이 없으므로 TRACE_FILE10과 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
    

    (일반적으로 전체 스크립트를 작은따옴표로 묶는 것이 더 일반적이므로 스크립트에서는 이스케이프하지 않습니다 $. 이 경우 bash 변수를 사용할 수 있도록 스크립트를 큰따옴표로 묶으므로 백슬래시 이스케이프가 필요합니다. 쉘이 자체 쉘로 교체되는 것을 방지하기 위해)$2awkawkawk$ORACLE_SIDawkawk$2$2

  3. ps배관 grep등 을 할 필요가 없습니다 awk. 당신도 이것을 할 수 있습니다 ps h -o cmd -C pmon. 또는 pgrep.

  4. sed. 및 기타 모든 표준 텍스트 처리 도구 cat에 연결하지 않고 파일 자체를 읽을 수 있습니다 sed.grepawkperlcut

  5. [ -n "$var" ]동일합니다 [ ! -z "$var" ].

    -z빈 문자열을 테스트하고, -n비어 있지 않은 문자열을 테스트합니다.

  6. 어떤 경우에는 변수를 큰따옴표로 묶지 않았습니다. 변수를 사용할 때는 (거의) 항상 큰따옴표로 묶어야 합니다.

  7. 고정된 리터럴 문자열에는 작은따옴표가 사용됩니다. 큰따옴표는 문자열에 변수나 명령 대체를 삽입하려는 경우에 사용됩니다.

  8. 들여쓰기가 8자 너무 많습니다. 들여쓰기 수준당 2~4개의 공백을 사용합니다. 또는 편집기에서 탭 정지를 2~4개의 공백으로 설정하세요.

  9. 자신의 변수에 소문자 또는 대소문자 혼합을 사용하고 표준 유틸리티 및 범용 프로그램용으로 모든 대문자 변수 이름을 예약하는 것이 좋습니다.

  10. sqlplus, Letter" 소스 mysql와 같은 도구 입니다. psql입력 데이터의 유효성을 검사하고 삭제하지 않으면 스크립트가 손상되기 쉽습니다. SQL 주입 오류를 생성하는 것도 마찬가지로 쉽습니다.

    사소한 SQL 쿼리의 경우 SQL 명령에서 변수를 참조할 때 발생하는 문제를 피하기 위해 자리 표시자를 지원하는 데이터베이스 라이브러리가 있는 다른 언어를 perl배워야 합니다.python

관련 정보