[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 / <
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
N 2 (Cron Daemon) Wed Nov 2 23:05 25/924 "Cron
&
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
2 (Cron Daemon) Wed Nov 2 23:05 26/935 "Cron
>N 3 (Cron Daemon) Mon Nov 7 09:11 25/920 "Cron
& 3
Message 3:
From oracle@LIS-DB.localdomain Mon Nov 7 09:11:02 2022
Return-Path:
X-Original-To: oracle
Delivered-To: oracle@LIS-DB.localdomain
From: "(Cron Daemon)"
To: oracle@LIS-DB.localdomain
Subject: Cron
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
Precedence: bulk
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
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 / <
exit;
EOF
exec 1>&2
--//中午12点验证看看.收尾取消上面测试定义的crontab内容.注我没有等到中午,我自己修改crontab执行时间测试ok.
--//然后在修改回来.
# crontab -u oracle -l
5 23 * * * /home/del_log/del_arc.sh
--//一些收尾忽略.包括删除/var/spool/mail里面记录的垃圾.