我正在尝试使用 crontb 安排此脚本每天运行:
#/bin/bash
cd /home/banana/gdrive
DATE=`date +%Y-%m-%d`
mongodump --gzip --archive=$DATE
./gdrive upload ./$DATE
olddate="$(date "+%Y-%m-%d" -d "9 days ago")"
old2=$(date -d $olddate +%s)
#echo $old2
list="$(./gdrive list)"
#echo $list
ADDR=(${list// / })
ii=0
for i in "${ADDR[@]:5}"; do
if [ $(($ii % 7)) -eq 0 ]; then
id=$i
fi
if [ $(($ii % 7)) -eq 1 ]; then
name=$i
dat=$(date -d $name +%s)
#echo $dat
if [ $old2 -ge $dat ]; then
echo "delete"
echo $id
touch $id
./gdrive delete $id
fi
#echo "name"
#echo $name
#echo $id
fi
#echo $ii
#echo $i
let ii=ii+1
done
crontab 条目:
0 2 * * * /home/banana/gdrive/upload.sh
如果在 bash 控制台中启动,脚本运行良好,如果它由 crontab 运行,即使我无法在任何地方找到任何记录的错误,它也无法到达最后。
通过模拟使用 crontab 环境,如下所建议:https://serverfault.com/questions/85893/running-a-cron-job-manually-and-immediately/85906
我发现执行结果出现错误:
gdrive/upload.sh: 12: gdrive/upload.sh: Syntax error: "(" unexpected
鉴于 crontab 环境中的 SHELL 变量设置为 SHELL=/bin/sh 并且那里的语法是 bash,这听起来很合理(即使我仍然对脚本第一行中 #/bin/bash 的作用感到困惑)。
问题是,即使在 crontab 文件中放入 SHELL=/bin/bash 后,结果仍然相同。
所以问题是,这个设置有什么问题? 如何使用 crontab 来安排这个脚本?
答案1
需要写的内容包含感叹号。
#!/bin/bash
尝试在你的 shell 脚本的第一行写入。
答案2
补充@torusJKL 的回答:
分析有问题的行ADDR=(${list// / })
,它将中存在的所有多个空格转换$list
为只有一个空格(此构造替换变量内的文本:${variable//old/new}
更改每个和全部字符串‘old’替换$variable
字符串‘new’)。
如果结果字符串以空格开头和结尾,则结果为ADDR=( word1 word2 word3 )
,在 Bash 中创建一个数组$ADDR[]
,即ADDR=([0]="word1" [1]="word2" [2]="word3")
(确认条件中for
出现所有元素${ADDR[@]}
,但使用 :5 删除/跳过前四个元素)。如果元素少于五个,则条件为空,并for
跳过主体。
如果周围没有空格,$ADDR
则只包含一个数据(如果有内部空格,则为“word1”或“word1 word2 word3”;也可能为空或单个空格“ ”),然后${ADDR[@]}
返回该数据并且${ADDR[@]:5}
始终为空,因为元素不超过四个。
问题是,计划任务默认运行命令什和什不支持数组,因此它会响应错误,而不是$ADDR
按预期构建数组。强制解释器猛击#!/bin/bash
正如@torusJKL 所说,在第一行使用 shebang解决了这个问题。