[20221107]除錯crontab問題.txt

lfree發表於2022-11-09

[20221107]除錯crontab問題.txt

--//上個星期遇到的問題,對方編輯的刪除archivelog的執行指令碼如下透過crontab呼叫:

# cat /home/del_log/del_arc.sh
source ~/.bash_profile
exec >> /home/del_log/log/del_arch`date +%F-%H`.log
/u01/app/oracle/product/19/db_1/bin/rman target / <<EOF
delete noprompt archivelog until time 'sysdate-10';
exit;
EOF

--//郵件記錄錯誤如下:
$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/oracle": 2 messages 2 new
>N  1 (Cron Daemon)         Tue Nov  1 23:05  25/924   "Cron <oracle@LIS-DB> /home/del_log/del_arc.sh"
 N  2 (Cron Daemon)         Wed Nov  2 23:05  25/924   "Cron <oracle@LIS-DB> /home/del_log/del_arc.sh"
&
Message  1:
From oracle@LIS-DB.localdomain  Tue Nov  1 23:05:02 2022
...
Status: R

/home/oracle/.bashrc: line 14: `==': not a valid identifier

--//檢查/home/oracle/.bashrc,發現在.bashrc中我定義函式:
== ()
{
    local in="$(echo "$@" | sed -e 's/\[/(/g' -e 's/\]/)/g')";
    echo $in | bc -lq | tr -d '\\\r' | sed -e "s/\.\([0-9]*[1-9]\)0\+$/.\1/" -e "s/\.0\+$//"
}

--//理論執行沒有問題的.不知道為什麼透過crontab呼叫會報錯.
--//我個人不建議使用source ~/.bash_profile 這樣的呼叫模式,而且直接將相關環境變數寫入指令碼中.
--//這樣呼叫首先執行~/.bash_profile => ~/.bashrc => /etc/bashrc,然後繼續執行.
--//首先如果某人修改.bash_profile,.bashrc,/etc/bashrc 出現異常等不可預測的情況,再比如多個資料庫例項.如果預設修改
--//ORACLE_SID,導致刪除另外的資料庫歸檔,而修改者並不知道存在這樣的操作.
--//該問題先放一放,檢查為什麼.bashrc中我定義函式 == 報錯的問題.

1.建立TT.sh指令碼:
# cat /home/del_log/TT.sh
source ~/.bash_profile
exec >> /home/del_log/TT.log
echo this is a test $(date +%F-%T)

# chmod 777 TT.sh

2.編輯crontab檔案:
$ crontab -e
$ crontab -l
5 23 * * * /home/del_log/del_arc.sh
* 9 * * * /home/del_log/TT.sh

3.問題再現:
--//mail有記錄.
 $ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/oracle": 3 messages 1 new
    1 (Cron Daemon)         Tue Nov  1 23:05  26/935   "Cron <oracle@LIS-DB> /home/del_log/del_arc.sh"
    2 (Cron Daemon)         Wed Nov  2 23:05  26/935   "Cron <oracle@LIS-DB> /home/del_log/del_arc.sh"
>N  3 (Cron Daemon)         Mon Nov  7 09:11  25/920   "Cron <oracle@LIS-DB> /home/del_log/TT.sh"
& 3
Message  3:
From oracle@LIS-DB.localdomain  Mon Nov  7 09:11:02 2022
Return-Path: <oracle@LIS-DB.localdomain>
X-Original-To: oracle
Delivered-To: oracle@LIS-DB.localdomain
From: "(Cron Daemon)" <oracle@LIS-DB.localdomain>
To: oracle@LIS-DB.localdomain
Subject: Cron <oracle@LIS-DB> /home/del_log/TT.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
Precedence: bulk
X-Cron-Env: <XDG_SESSION_ID=204603>
X-Cron-Env: <XDG_RUNTIME_DIR=/run/user/502>
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/oracle>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=oracle>
X-Cron-Env: <USER=oracle>
Date: Mon,  7 Nov 2022 09:11:01 +0800 (CST)
Status: R
/home/oracle/.bashrc: line 14: `==': not a valid identifier

4.修改函式:
--//自己也猜測 == 定義函式是否特殊,換成js 測試.
--//確實問題解決,為什麼呢.
--//難道==在shell中非常特殊碼?

5.修改TT.sh指令碼:
--//仔細檢查,對方沒有寫開頭的BANG(#),自己加入看看.

# cat /home/del_log/TT.sh
#! /bin/bash
source ~/.bash_profile
exec >> /home/del_log/TT.log
echo this is a test $(date +%F-%T)

--//重新定義函式為==,測試:
--//OK.沒有問題,也就是預設crontab呼叫的/bin/sh,這樣加入前面的BANG(#) 採用/bin/bash,問題消失.
--//很明顯對方編寫shell指令碼太不專業了,而且工作非常不負責.

--//可以使用一個簡單的例子驗證:

$ cat aa.txt
js ()
{
    local in="$(echo "$@" | sed -e 's/\[/(/g' -e 's/\]/)/g')";
    echo $in | bc -lq | tr -d '\\\r' | sed -e "s/\.\([0-9]*[1-9]\)0\+$/.\1/" -e "s/\.0\+$//"
}

$ /bin/sh aa.txt
--//OK,透過沒有報錯.
--//修改如下:

$ cat aa.txt
== ()
{
    local in="$(echo "$@" | sed -e 's/\[/(/g' -e 's/\]/)/g')";
    echo $in | bc -lq | tr -d '\\\r' | sed -e "s/\.\([0-9]*[1-9]\)0\+$/.\1/" -e "s/\.0\+$//"
}

$ /bin/sh aa.txt
aa.txt: line 5: `==': not a valid identifier

--//報錯而且與mail裡面記錄的資訊一致.

--//最終我修改如下:
# cat  del_arc.sh
#! /bin/bash
#source ~/.bash_profile

export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/19/db_1
export PATH=.:${PATH}:$HOME/bin:$ORACLE_HOME/bin:/u01/ogg122
export ORACLE_SID=orcl
export NLS_LANG=AMERICAN_AMERICA.zhs16gbk
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export LD_LIBRARY_PATH
export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
export NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF'
export NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF'

exec >> /home/del_log/log/del_arch`date +%F-%H`.log
/u01/app/oracle/product/19/db_1/bin/rman target / <<EOF
delete noprompt archivelog until time 'sysdate-10';
exit;
EOF
exec 1>&2

--//中午12點驗證看看.收尾取消上面測試定義的crontab內容.注我沒有等到中午,我自己修改crontab執行時間測試ok.
--//然後在修改回來.

# crontab -u oracle -l
5 23 * * * /home/del_log/del_arc.sh

--//一些收尾忽略.包括刪除/var/spool/mail裡面記錄的垃圾.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2922653/,如需轉載,請註明出處,否則將追究法律責任。

相關文章