我有一个 crontab:
* * * * * /home/ipa/web/backup.sh > /dev/null 2>&1
(不,它不是每分钟运行一次,只是在这里测试)
backup.sh 有以下内容:
#!/usr/bin/env sh
sqlite3 /home/ipa/web/ipa_django/mysite/db.sqlite3 ".backup 'backup_file.sqlite3'"
src="/home/ipa/web/backup_file.sqlite3"
let seconds=$(date +%H)*3600+$(date +%M)*60+$(date +%S)
echo $seconds
filename="db.sqlite3"
echo $filename.$seconds
dest="/home/ipa/web/db_backups/"$filename.$seconds
cp $src $dest
cd /home/ipa/web/db_backups
tar -cvzf ipadbbackup.tar.gz $filename.$seconds
cd /home/ipa/web/
cp /home/ipa/web/db_backups/ipadbbackup.tar.gz ipadbbackup.tar.gz
rm /home/ipa/web/db_backups/$filename.$seconds
rm /home/ipa/web/db_backups/ipadbbackup.tar.gz
#rm "$srcfile"
/usr/bin/bash start-app.sh;
echo "Running email backup"
python2.7 backup_via_email.py
rm ipadbbackup.tar.gz
我的想法是,将数据库复制到一个临时区域,将其压缩并复制到另一个.py 文件可以找到的地方,然后通过电子邮件将其作为备份发送出去。
问题是:
如果我从其所在位置运行此脚本:/home/ipa/web/
使用 ./backup.sh
它运行良好,我收到的电子邮件中的文件运行良好:db.sqlite3.77627
或者什么不是...问题是当它作为 cron 运行时文件不完整并且文件名是:
db.sqlite3。
我不明白为什么以 cron 方式运行会导致它失败?tar 中的文件也小了 2.1k?所以不确定发生了什么... 甚至不知道该去哪里查找。
答案1
最有可能的是,当您手动运行时您实际上并没有运行./backup.sh
,而是bash ./backup.sh
。
通过 shell 计算值的唯一符合 POSIX 标准的方法是使用$(( expr ))
。
一般来说,除非有非常充分的理由,否则脚本应该使用 bash,因为大多数人不知道 sh 和 bash 之间的区别,只会编写不完整的脚本。
#!/usr/bin/env bash
set -e
set -u
declare -r db_src="/home/ipa/web/ipa_django/mysite/db.sqlite3"
declare -r db_bak="/home/ipa/web/backup_file.sqlite3"
declare -r db_dst="/home/ipa/web/db_backups/db.sqlite3.$[ EPOCHSECONDS % 86400 ]"
sqlite3 "${db_src}" ".backup 'backup_file.sqlite3'"
cp "${db_bak}" "${db_dst}"
cd "$( dirname "${db_dst}" )"
tar -czf "/home/ipa/web/ipadbbackup.tar.gz" "$( basename "${db_dst}" )"
rm "${db_dst}"
echo "Running email backup"
cd "/home/ipa/web"
python2.7 backup_via_email.py
rm ipadbbackup.tar.gz
在尝试调试时,务必记录你的 cron 输出,我猜你已经command not found: let
在某处看到过了。