我提出的问题是: 我想要一个可以为我的所有重要文件创建备份的程序。
尽管这是一个简单的问题,但是问题本身并没有给我们足够的信息来解决它。进一步的分析是必需的。例如,我们如何确定该备份哪些文件?备份保存在哪里?我们怎么样存储备份?
在恰当地分析了这个问题之后,我们开始设计我们的程序。我们列了一张表,表示我们的程序应该如何工作。对于这个问题,我已经创建了下面这个列表以说明我 如何让它工作。如果是你设计的话,你可能不会这样来解决问题——每个人都有其做事的方法,这很正常。
需要备份的文件和目录由一个列表指定。
备份应该保存在主备份目录中。
文件备份成一个zip文件。
zip存档的名称是当前的日期和时间。
我们使用标准的zip命令,它通常默认地随Linux/Unix发行版提供。Windows用户可以使用Info-Zip程序。注意你可以使用任何地存档命令,只要它有命令行界面就可以了,那样的话我们可以从我们的脚本中传递参数给它。
#!/usr/bin/python
# Filename: backup_ver4.py
import
os
import
time
# 1. The files and directories to be backed up are specified in a list.
source = [
'/home/swaroop/byte'
,
'/home/swaroop/bin'
]
# If you are using Windows, use source = [r'C:\Documents', r'D:\Work'] or something like that
# 2. The backup must be stored in a main backup directory
target_dir =
'/mnt/e/backup/'
# Remember to change this to what you will be using
# 3. The files are backed up into a zip file.
# 4. The current day is the name of the subdirectory in the main directory
today = target_dir +
time
.strftime(
'%Y%m%d'
)
# The current time is the name of the zip archive
now =
time
.strftime(
'%H%M%S'
)
# Take a comment from the user to create the name of the zip file
comment =
raw_input
(
'Enter a comment --> '
)
if
len
(comment) ==
0
:
# check if a comment was entered
target = today +
os
.sep + now +
'.zip'
else
:
target = today +
os
.sep + now +
'_'
+ \
comment.replace(
' '
,
'_'
) +
'.zip'
# Notice the backslash!
# Create the subdirectory if it isn't already there
if not
os
.path.exists(today):
os
.mkdir(today)
# make directory
print
'Successfully created directory'
, today
# 5. We use the zip command (in Unix/Linux) to put the files in a zip archive
zip_command =
"zip -qr '%s' %s"
% (target,
' '
.join(source))
# Run the backup
if
os
.system(zip_command) ==
0
:
print
'Successful backup to'
, target
else
:
print
'Backup FAILED'
$ python backup_ver4.py
Enter a comment --> added new examples
Successful backup to /mnt/e/backup/20041208/082156_added_new_examples.zip
$ python backup_ver4.py
Enter a comment -->
Successful backup to /mnt/e/backup/20041208/082316.zip
这个程序现在工作了!让我们看一下版本三中作出的实质性改进。我们使用raw_input
函数得到用户的注释,然后通过len
函数找出输入的长度以检验用户是否确实输入了什么东西。如果用户只是按了回车(比如这只是一个惯例备份,没有做什么特别的修改),那么我们就如之前那样继续操作。
然而,如果提供了注释,那么它会被附加到zip归档名,就在.zip
扩展名之前。注意我们把注释中的空格替换成下划线——这是因为处理这样的文件名要容易得多。
但是它仍然有进一步改进的空间。比如,你可以在程序中包含 交互 程度——你可以用-v
选项来使你的程序更具交互性。
另一个可能的改进是使文件和目录能够通过命令行直接传递给脚本。我们可以通过sys.argv
列表来获取它们,然后我们可以使用list
类提供的extend
方法把它们加到source
列表中去。
我还希望有的一个优化是使用tar命令替代zip命令。这样做的一个优势是在你结合使用tar和gzip命令的时候,备份会更快更小。如果你想要在Windows中使用这些归档,WinZip也能方便地处理这些.tar.gz
文件。tar命令在大多数Linux/Unix系统中都是默认可用的。Windows用户也可以下载安装它。
命令字符串现在将称为:
tar =
'tar -cvzf %s %s -X /home/swaroop/excludes.txt'
% (target,
' '
.join(srcdir))
选项解释如下:
-c
表示创建一个归档。
-v
表示交互,即命令更具交互性。
-z
表示使用gzip滤波器。
-f
表示强迫创建归档,即如果已经有一个同名文件,它会被替换。
-X
表示含在指定文件名列表中的文件会被排除在备份之外。例如,你可以在文件中指定*~
,从而不让备份包括所有以~
结尾的文件。
重要
最理想的创建这些归档的方法是分别使用zipfile
和tarfile
。它们是Python标准库的一部分,可以供你使用。使用这些库就避免了使用os.system
这个不推荐使用的函数,它容易引发严重的错误。
然而,我在本节中使用os.system
的方法来创建备份,这纯粹是为了教学的需要。这样的话,例子就可以简单到让每个人都能够理解,同时也已经足够用了。