使用 Bourne shell 脚本时 CRON 作业行为不稳定

使用 Bourne shell 脚本时 CRON 作业行为不稳定

我有以下脚本,当我在提示符下键入脚本名称(logscript)时,该脚本正常运行:

#!/bin/sh
dvar=`date +"%m\/%d\/%y"`
filedate=`date +%b%d%Y`
echo DSS1 > serverlog_${filedate}.txt
grep "^$dvar" oasErrLog >> serverlog_${filedate}.txt
echo CMX1 >> serverlog_${filedate}.txt
ssh GVECMX1 grep "^$dvar" /home/gve/log/oasErrLog >> serverlog_${filedate}.txt
echo CMX2 >> serverlog_${filedate}.txt
ssh GVECMX2 grep "^$dvar" /home/gve/log/oasErrLog >> serverlog_${filedate}.txt
echo XIS1 >> serverlog_${filedate}.txt
ssh GVEXIS1 grep "^$dvar" /home/gve/log/oasErrLog >> serverlog_${filedate}.txt
echo XIS2 >> serverlog_${filedate}.txt
ssh GVEXIS2 grep "^$dvar" /home/gve/log/oasErrLog >> serverlog_${filedate}.txt
scp serverlog_${filedate}.txt "GVEXOSR2:C:/Documents\ and\ Settings/gve/Desktop/logs"
#rm serverlog_${filedate}.txt

正常输出示例为:

DSS1
01/11/10 03:00:08.139 XIS run_backupserver - Startup of XISBACKUP backupserver complete.
CMX1
01/11/10 04:30:05.710 OMNICOMM 30274 - boatimesync: error 3 from boaRx rtu 35 pretry 1 {protocols/boa/boa_command.c:601}
01/11/10 04:30:12.117 OMNICOMM 30274 - CRC (0FFC) does not match calculated CRC (03B0) for remote JRS. headerLength=5 dataLength=0 crcByteOffset=2  functionCode=1  {protocols/boa/boa_io.c:1177}    
CMX2
XIS1
XIS2
01/11/10 03:00:10.563 XIS run_backupserver - Startup of XISBACKUP backupserver complete.

但是当我设置 CRON 作业时,它会运行并 scp 文件,但内容是错误的,并且文件不在服务器上(当 rm 行被注释掉时,如我上面所示)。这是我得到的输出,但请注意:输出会发生变化,输出的内容会有所不同:

DSS1
CMX1
01/11/10 001/11/10 04:30:05.710 OMNICOMM 30274 - boatimesync: error 3 from boaRx rtu 35 pretry 1 {protocols/boa/boa_command.c:601}
01/11/10 04:30:12.117 OMNICOMM 30274 - CRC (0FFC) does not match calculated CRC (03B0) for remote JRS. headerLength=5 dataLength=0 crcByteOffset=2  functionCode=1  {protocols/boa/boa_io.c:1177}
CMX2
CMX2
CMX2
CMX2
XIS1
XIS1
XIS1
XIS1
XIS2
01/1101/11/10 001/11/10 03:00:10.563 XIS run_backupserver - Startup of XISBACKUP backupserver complete.

为什么 CRON 作业没有像系统在手动输入命令时运行的那样运行?

编辑: 我已将脚本修改为循环并使用所有绝对寻址,并使用 SHELL、PATH 和 HOME 变量修改了 CRON 文件,但输出仍然不稳定,这是现在的脚本:

#!/bin/sh

### internal variable definitions
dvar=`date +"%m\/%d\/%y"`
filedate=`date +%b%d%Y`

# add the prefix of new hosts into the string below
# which will be expanded later into GVE(whatever) while looping
HOSTLIST="DSS1 CMX1 CMX2 XIS1 XIS2"

# main Loop
for SUFFIX in $HOSTLIST
do
  echo $SUFFIX >> /home/gve/log/serverlog_${filedate}.txt
  ssh GVE$SUFFIX grep "^$dvar" /home/gve/log/oasErrLog \
    >> /home/gve/log/serverlog_${filedate}.txt
  echo "\n" >> /home/gve/log/serverlog_${filedate}.txt
done

# transfer and delete file
scp /home/gve/log/serverlog_${filedate}.txt \
  "GVEXOSR2:C:/Documents\ and\ Settings/gve/Desktop/logs"
#rm serverlog_${filedate}.txt

输出如下:

DSS1
01/1201/12/10 03:00:08.323 XIS run_backupserver - Startup of XISBACKUP backupserver complete.
1
01/12/101/12/10 00:00:37.003 agc - dbioLower: DNP prev cmd may still in prog, name NPC_GT3_GOV raiseTimeout 1250 lowerTimeout 2500 curtime(1263286837:3) cmd_time(1263286834:807)
01/12/10 02:14:57.545 OMNICOMM 1562 - CRC (F110) does not match calculated CRC (1110) for remote ARS. headerLength=5 dataLength=10 crcByteOffset=7  functionCode=2  {protocols/boa/boa_io.c:1177}


CMX2


XIS1


XIS1


XIS2
01/12/101/12/10 03:00:10.408 XIS run_backupserver - Startup of XISBACKUP backupserver complete.

请注意,有些行上的日期是混乱的,‘CMX1’写成了‘1’,还有重复的‘XIS1’。

最终编辑:

看起来 CRON 不知怎么地产生了多个相互干扰的进程。在终止所有适用的进程后,它就恢复正常了。CRON 有产生多进程故障的历史记录(如果您在网上搜索一下),所以要当心。

答案1

cron 的第一条规则是设置您期望的几件事。第一,您所在的目录(明确地“cd”到该目录)。第二,您期望的路径(在 crontab 中,PATH=...)和第三,邮件发往何处(如果您想更改它。)

例如:

SHELL=/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
HOME=/var/log

然后,我还会让每个脚本根据需要设置其他路径,并且始终

cd $HOME

或另一条显式路径。

答案2

CRON 确实有它自己的环境。

您是否以运行该作业的用户身份使用 crontab -e 安装该作业?该作业是如何添加的?

另外,对脚本进行一些重做,并加入循环;这应该可以在您的设置上正常运行。

#!/bin/sh

### internal variable definitions
dvar=`date +"%m\/%d\/%y"`
filedate=`date +%b%d%Y`

# add the prefix of new hosts into the string below,
# which will be expanded later into GVE{whatever} while looping
HOSTLIST="DSS1 CMX1 CMX2 XIS1 XIS2"

# main processing loop
for SUFFIX in $HOSTLIST
do
  echo $SUFFIX >> serverlog_${filedate}.txt     
  ssh GVE$SUFFIX grep "^$dvar" /home/gve/log/oasErrLog \
    >> serverlog_${filedate}.txt
done

scp serverlog_${filedate}.txt \
  "GVEXOSR2:C:/Documents\ and\ Settings/gve/Desktop/logs"

第二次尝试的后续行动:

好的,所以肯定是出了问题。您得到 2x XIS1 这一事实很好地表明缓冲区未正确写入,或者 shell 本身就是罪魁祸首。循环应该在运行时隔离每个主机,因此除非您有未刷新的管道/缓冲区/您周围有什么东西,否则它不应该连续两次显示 XIS1。尝试明确使用#!/bin/bash作为 shell 而不是 sh,有时供应商会将 sh 重新挂接到 bash 以外的其他东西(并且循环是 bash-ism,因此可能会导致问题)。此外,在脚本中将 a 放在 thesync之前done,看看它是否是缓冲问题。

相关内容