根據變數的輸出執行塊
下面是我起草的腳本,它將根據它將從中獲得的 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
. 例如,而不是:ps -eaf | grep pmon | grep -v grep | awk '{print $8}'
你可以做:
ps -eaf | awk '/pmon/ && ! /grep/ {print $8}'
grep
類似地,管道cut
通常最好使用awk
. 例如,而不是:cat /etc/oratab | grep ^$ORACLE_SID | cut -d":" -f2
採用
awk -F: "/^$ORACLE_SID/ {print \$2}" /etc/oratab
(通常你不會在腳本中轉義
$
of ,因為更常見的是單引號整個腳本。在這種情況下,我們是雙引號腳本,以便我們可以使用 bash 變數,所以我們需要反斜杠轉義以防止外殼用自己的替換它)$2``awk``awk``awk``$ORACLE_SID``awk``awk``$2``$2
3. 你不需要做管道ps
或grep
無論如何awk
。你可以這樣做ps h -o cmd -C pmon
。或使用pgrep
. 4.sed
可以自己讀取文件,你不需要管道cat
到sed
. 其他標准文本處理工具也grep
可以。awk``perl``cut
5.[ -n "$var" ]
是一樣的[ ! -z "$var" ]
。
-z
測試空字元串,-n
測試非空字元串。 6. 有幾次你沒有雙引號你的變數。當你使用它們時,你應該(幾乎)總是用雙引號引起來。 7. 單引號用於固定的文字字元串。雙引號用於將變數或命令替換插入字元串時。 8. 縮進 8 個字元是多餘的。每個縮進級別使用 2 或 4 個空格。或將編輯器中的製表位設置為 2 或 4 個空格。 9. 對您自己的變數使用小寫或 MixedCase 是一個好習慣,而將 ALLCAPS 變數名留給標準實用程序和常用程序。 10.sqlplus
,mysql
,等工具psql
對於在 sh 或 bash 等中執行腳本數據庫查詢非常方便,但您必須非常小心使用 SQL 命令的任何變數 - 特別是如果變數中的值來自使用者提供的數據,或者其他“不受信任”的來源。如果輸入數據未經驗證和未經處理,很容易破壞腳本。創建 SQL 注入錯誤同樣容易。對於非平凡的 SQL 查詢,您可能應該學習
perl
或python
使用支持佔位符的數據庫庫的其他語言,以避免在 sql 命令中引用變數時出現任何問題。