对于crontab调用的程序,我们要一定要注意引号和相对路径,不然会给你导致无穷的问题。 阿健同学写了cron程序,部署在所有的服务器上,但是在一台服务器上怎么都会报一个错误,导致结果失败。 可所有的程序都是一模一样的。 主要代码如下, 脚本其实很简单.
1 2 3 4 5 6 7 8 9 10 11
| TEST_SIZE=`ls -l /opt/buffer/ | grep test* | awk '{print $5}'` TEST_DATE=`ls -l /opt/buffer/ | grep test* | awk '{print $6, $7, $8}'` if [ $TEST_SIZE -ge 0 ]; then echo $TEST_SIZE > /mnt/log/88/TEST_SIZE.log echo $TEST_DATE > /mnt/log/88/TEST_DATE.log echo $TEST_DATE > /mnt/log/88/TEST_ORI.log else echo "null" > /mnt/log/fluentd/88/TEST_SIZE.log more /mnt/log/88/TEST_ORI.log > /mnt/log/88/TEST_DATE.log fi
|
看着也没有什么大错,虽然有点挫吧,但是该有的判断也都有的. 于是用set -x打开shell的调试,发现了一个错误
1
| [: -ge: unary operator expected
|
这个很明显是一边没有获得到值导致的错误.于是再往上看,发现在grep的时候, 程序里写的是 grep test*, 可在这里变成了 grep test_abc.log . 用find找了一下,果然在/root目录下发现了test_abc.log 这个问题, 而这个crontab是运行在root账户下. 我们在脚本里加上export看它是在哪个目录中执行的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| declare -x CVS_RSH="ssh" declare -x G_BROKEN_FILENAMES="1" declare -x HISTSIZE="1000" declare -x HOME="/root" declare -x HOSTNAME="tk04.tk.hk" declare -x INPUTRC="/etc/inputrc" declare -x LANG="en_US.UTF-8" declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s" declare -x LOGNAME="root" declare -x LS_COLORS="" declare -x MAIL="/var/spool/mail/root" declare -x OLDPWD declare -x PATH="/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/ruby/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin:/bin" declare -x PWD="/root" declare -x SHELL="/bin/sh" declare -x SHLVL="2" declare -x USER="root"
|
那就很明白了. 原来当前目录就是/root啊。而你在 test* 的时候因为/root目录下只有test_abc.log, 所以自动补全成(这应该是一个典型的bug)test_abc.log 了。 而如果 /root 还有别的如 test_def.log 那理论上应该不会自动补全了。 至于bash为什么要做这样的处理,我们只能参考源码了。 而且我们得小心不同版本之间的区别。 所以实际经验就是加引号。 单引号和双引号在这里是没有区别的,但是大部分场合是有很大区别的。 以及``和$() 之间的区别也要清楚,这些就放到以后再说吧。