最近在搭建服务器时需要每天对数据库里的内容进行备份,所以简单学习了下crontab这个命令的使用方式。
目标
- 每天凌晨1点对数据库进行备份
- 每次备份后将数据库文件加上时间戳并存储到指定文件夹
- 备份完成后在log里写入当前时间和备份文件名
先写一个bash脚本
#! /bin/bash
cur_time=$(date +%Y_%m_%d_%k_%M_%S) #获取当前时间,并按照 年_月_日_小时_分钟_秒 的格式存储
file_name=./db_backup/db.sqlite3.bak_$cur_time #将刚获取的时间接在备份文件名的后面
sqlite3 db.sqlite3 .dump > $file_name #对一个sqlite数据库进行备份
now=$(date +'%x %X') #获取现在的时间
output=$(printf "[ %s ] db backed @ %s" "$now" "$file_name") #写一行log
echo $output >> ~/logs/cron.log #将log写入指定文件
将上述文件保存为一个脚本,比如backup.sh
再来添加定时重复的工作
在Linux下使用crontab这个命令可以做到:
- crontab -e | 编辑你的定时工作脚本
- crontab -l | 查看你的工作脚本
- crontab -r | 删除你的工作脚本
- crontab -l > 文件名 | 将你的脚本备份到一个文件里
- crontab 文件名 | 将指定文件的内容复制到你的工作脚本
编辑定时工作脚本
首先通过下面的命令来创建一个脚本,如果你有设置系统默认的文本编辑器的话,则该文件会在默认的编辑器下打开
crontab -e
如果输入完上述命令后你得到的结果是:
no crontab for root - using an empty one
888
则说明你还没有设置默认的文本编辑器,可以通过下面的命令来设置:
export EDITOR=nano
上面例子中使用了nano,但你可以随意替换成pico、vi等任意编辑器。设置好后,再次执行crontab -e
我希望每天凌晨一点自动备份一下数据库,那么我会在crontab的文件里这么写:
0 1 * * * /home/cheng/backup.sh
第一个0代表0分,1代表1点,后面的三个*分别代表日,月,周日。最后的文件路径是你需要执行的脚本。
前五个数值的范围分别为:
- 分 0 - 59
- 小时 0 - 23
- 日 1 - 31
- 月 1 - 12
- 周日 sun, mon, tue, wed, thu, fri, sat (可以用这些缩写表示一周中的那一天,也可以用数字 0 - 7 表示, 注意0和7都是周日的意思)
下面是一些简单的示例:
每周日下午五点执行一次:
0 17 * * sun /scripts/script.sh
每6小时执行一次:
0 */6 * * * /scripts/script.sh
每分钟执行一次:
* * * * * /scripts/script.sh
找到一个很好的参考网站: http://tecadmin.net/crontab-in-linux-with-20-examples-of-cron-schedule/
Crontab文件的存储位置
每个用户通过crontab -e创建的脚本文件会被存储在:
cd /var/spool/cron/crontabs/
这个文件夹下每个用户的脚本文件会以该用户的用户名进行区分存储。
Reference:
http://www.ibm.com/developerworks/library/l-job-scheduling/
I was running a Django server on Ubuntu 12.04 and saw a lot of errors logged in gunicorn's error log file:
error: [Errno 111] Connection refused
One line of the error messages caught my eye, send_mail. Gunicorn is trying to send my the error message via the send_mail() function but failed. I realized that I didn't setup the email settings in settings.py.
I searched online for a solution and found two:
- send email via Gmail's smtp
- setup your mail server
Option 1 seems like a quick and dirty way to get things done, but it has a few drawbacks:
- Sending email via Gmail's smtp means the FROM field will be your Gmail address rather than your company or whatever email address you want it to be.
- To access Gmail, you need to provide your username and password. This means you have to store your gmail password either in the settings.py file or to be more discreet in an environment variable.
- You have to allow less secured app to access your gmail. This is a setting in your gmail's account.
I decided to setup my own mail server because I don't want to use my personal email for contacting clients. To do that, I googled and found that there are two mail servers that I can use:
- postfix
- sendmail
Since postfix is newer and easier to config, I decided to use it.
- Install postfix and Find main.cf
Note: main.cf is the config for postfix mail server
sudo apt-get install postfix
postfix is already the newest version.
postfix set to manually installed.
Great, it is already installed. Then, I went to /etc/postfix/ to find main.cf and it is not there! Weird, so I tried to reinstall postfix:
sudo apt-get install --reinstall postfix
After installation, I saw a message:
Postfix was not set up. Start with
cp /usr/share/postfix/main.cf.debian /etc/postfix/main.cf
. If you need to make changes, edit
/etc/postfix/main.cf (and others) as needed. To view Postfix configuration
values, see postconf(1).
After modifying main.cf, be sure to run '/etc/init.d/postfix reload'.
I see. So, I followed the instruction and copied the main.cf file to /etc/postfix/:
cp /usr/share/postfix/main.cf.debian /etc/postfix/main.cf
Add the following lines to main.cf:
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mydestination = localhost
Then, reload this config file:
/etc/init.d/postfix reload
Now, let's test to see if we can send an email to our mailbox via telnet:
telnet localhost 25
Once connected, enter the following line by line:
mail from: whatever@whatever.com
rcpt to: your_real_email_addr@blah.com
data (press enter)
type whatever content you feel like to type
. (put an extra period on the last line and then press enter again)
If everything works out, you sould see a comfirmation message resemables this:
250 2.0.0 Ok: queued as CC732427AE
It is guaranteed that this email will end up in the spam box if you use Gmail. So take a look at your spam inbox to see if you received the test mail (it may take a minute to show up).
If you recevied the test email, then it means postfix is working properly. Now, let's config Django to send email via postfix.
First, I added the following line to my settings.py file:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 25
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
DEFAULT_FROM_EMAIL = 'Server <server@whatever.com>'
Then, I opened up Django shell to test it:
./manage.py shell
>>> from django.core.mail import send_mail
>>> send_mail('Subject here', 'Here is the message.', 'from@example.com',
['to@example.com'], fail_silently=False)
Again, check your spam inbox. If you received this mail, then it means Django can send email via postfix, DONE!
references:
http://stackoverflow.com/questions/5802189/django-errno-111-connection-refused
http://stackoverflow.com/questions/4798772/postfix-its-installed-but-how-do-i-test
http://stackoverflow.com/questions/26333009/django-postfix