昨天心血来潮搞的…
launchd是从Tiger开始加的系统服务加载系统, 大意就是可以让你按照某个特定的条件来触发某个程序的执行. 具体介绍可以看这里.
然后要做的就是
- 写个python脚本从FTP把整个网站拖下来
- launchd每星期自动执行一次这个脚本
FTP下载的脚本
就着ftplib的Sample写的, 可能会有Bug...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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() |
(Link)
launchd的配置文件
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
(Link)
每个launchd项目都要写个plist作为配置文件, 然后按其中的label命名放在~/Library/LaunchAgents
里. 详细语法可以看这里.
LaunchAgent
目录
launchctl load ~/Library/LaunchAgents launchctl list
list以后就可以看到服务在list里面了, 到时间就会在后台偷偷运行… 如果时间错过了会等到下次开机, 很智能的哦.
No comments:
Post a Comment