February 23, 2010

launchd自动备份FTP数据

昨天心血来潮搞的…

launchd是从Tiger开始加的系统服务加载系统, 大意就是可以让你按照某个特定的条件来触发某个程序的执行. 具体介绍可以看这里.

然后要做的就是

  • 写个python脚本从FTP把整个网站拖下来
  • launchd每星期自动执行一次这个脚本

FTP下载的脚本

就着ftplib的Sample写的, 可能会有Bug...

#! /usr/bin/python
### Copy everything on a FTP server to a local folder
from ftplib import FTP
import os.path
import datetime
def main():
#fill in the parameters here
ftpaddress = '1.1.1.1'
username = 'user'
password = 'pass'
backupfolder = '~/backup'
#create dir for today
backupfolder = os.path.expanduser(backupfolder)
if not os.path.exists(backupfolder):
os.makedirs(backupfolder)
os.chdir(backupfolder)
d = datetime.date.today()
localdir = d.strftime("%Y%m%d")
if not os.path.exists(localdir):
os.mkdir(localdir)
os.chdir(localdir)
#login FTP
f = FTP(ftpaddress)
f.login(username,password)
print ('logging in')
backupdir(f,'htdocs','htdocs')
if not os.path.exists('done'):
os.makedirs('done')
f.close()
def backupdir(f, remotedir, localdir):
print 'current remote dir: ', remotedir
print 'current local dir: ', os.path.abspath(localdir)
try:
f.cwd(remotedir)
except ftplib.error_perm, msg:
print "Can't chdir to", remotedir, ":", msg
else:
#prepare local dir
if not os.path.exists(localdir):
os.mkdir(localdir)
os.chdir(localdir)
subdirs = []
listing = []
filesfound = []
f.retrlines('LIST', listing.append)
for line in listing:
words = line.split(None, 8)
filename = words[-1].lstrip()
mode = words[0]
if mode[0] == 'd':
subdirs.append(filename)
continue
else:
filesfound.append(filename)
for file in filesfound:
savefile(f, file)
for subdir in subdirs:
backupdir(f, subdir, subdir)
f.cwd('..')
os.chdir('..')
def savefile(f, filename):
print "copying:", os.path.abspath(filename)
#delete local copy first
if(os.path.exists(filename)):
os.remove(filename)
#then duplicate
try:
fp = open(filename, 'wb')
except IOError, msg:
print "Can't create %r: %s" % (filename, msg)
else:
try:
f.retrbinary('RETR ' + filename, fp.write)
except ftplib.error_perm, msg:
print msg
fp.close()
if __name__ == '__main__':
main()
view raw ftpbackup.py hosted with ❤ by GitHub

(Link)

launchd的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.lizdo.ftpbackupweekly.plist</string>
<key>Program</key>
<string>/Users/Liz/Library/Scripts/FTPAutoBackup.php</string>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>1</integer>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>0</integer>
<key>Minute</key>
<integer>25</integer>
<key>Weekday</key>
<integer>2</integer>
</dict>
</dict>
</plist>
view raw gistfile1.xsl hosted with ❤ by GitHub

(Link)

每个launchd项目都要写个plist作为配置文件, 然后按其中的label命名放在~/Library/LaunchAgents里. 详细语法可以看这里.

搞定以后把它手动加到launchctl里, 不过每次开机也会自动scan上面的LaunchAgent目录
launchctl load ~/Library/LaunchAgents
launchctl list

list以后就可以看到服务在list里面了, 到时间就会在后台偷偷运行… 如果时间错过了会等到下次开机, 很智能的哦.

No comments: