關於第一份python腳本

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 name of the zip archive is the current date and time
target = target_dir + time.strftime('%Y%m%d%H%M%S') + '.zip'

# 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'

我們使用了ostime模塊,所以我們輸入它們。然後,我們在source列表中指定需要備份的文件和目錄。目標目錄是我們想要存儲備份文件的地方,它由target_dir變量指定。zip歸檔的名稱是目前的日期和時間,我們使用time.strftime()函數獲得。它還包括.zip擴展名,將被保存在target_dir目錄中。

time.strftime()函數需要我們在上面的程序中使用的那種定製。%Y會被無世紀的年份所替代。%m會被01到12之間的一個十進制月份數替代,其他依次類推。這些定製的詳細情況可以在《Python參考手冊》中獲得。《Python參考手冊》包含在你的Python發行版中。注意這些定製與用於print語句的定製(%後跟一個元組)類似(但不完全相同)

我們使用加法操作符來 級連 字符串,即把兩個字符串連接在一起返回一個新的字符串。通過這種方式,我們創建了目標zip文件的名稱。接着我們創建了zip_command字符串,它包含我們將要執行的命令。你可以在shell(Linux終端或者DOS提示符)中運行它,以檢驗它是否工作。

zip命令有一些選項和參數。-q選項用來表示zip命令安靜地工作。-r選項表示zip命令對目錄遞歸地工作,即它包括子目錄以及子目錄中的文件。兩個選項可以組合成縮寫形式-qr。選項後面跟着待創建的zip歸檔的名稱,然後再是待備份的文件和目錄列表。我們使用已經學習過的字符串join方法把source列表轉換爲字符串。

最後,我們使用os.system函數 運行 命令,利用這個函數就好像在 系統 中運行命令一樣。即在shell中運行命令——如果命令成功運行,它返回0,否則它返回錯誤號。

根據命令的輸出,我們打印對應的消息,顯示備份是否創建成功。好了,就是這樣我們已經創建了一個腳本來對我們的重要文件做備份!

第一個版本的腳本可以工作。然而,我們可以對它做些優化以便讓它在我們的日常工作中變得更好。這稱爲軟件的維護環節。

我認爲優化之一是採用更好的文件名機制——使用 時間 作爲文件名,而當前的 日期 作爲目錄名,存放在主備份目錄中。這樣做的一個優勢是你的備份會以等級結構存儲,因此它就更加容易管理了。另外一個優勢是文件名的長度也可以變短。還有一個優勢是採用各自獨立的文件夾可以幫助你方便地檢驗你是否在每一天創建了備份,因爲只有在你創建了備份,纔會出現那天的目錄。

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')

# 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

# The name of the zip file
target = today + os.sep + now + '.zip'

# 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'

兩個程序的大部分是相同的。改變的部分主要是使用os.exists函數檢驗在主備份目錄中是否有以當前日期作爲名稱的目錄。如果沒有,我們使用os.mkdir函數創建。

注意os.sep變量的用法——這會根據你的操作系統給出目錄分隔符,即在Linux、Unix下它是'/',在Windows下它是'\\',而在Mac OS下它是':'。使用os.sep而非直接使用字符,會使我們的程序具有移植性,可以在上述這些系統下工作。

第二個版本在我做較多備份的時候還工作得不錯,但是如果有極多備份的時候,我發現要區分每個備份是幹什麼的,會變得十分困難!例如,我可能對程序或者演講稿做了一些重要的改變,於是我想要把這些改變與zip歸檔的名稱聯繫起來。這可以通過在zip歸檔名上附帶一個用戶提供的註釋來方便地實現。

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'

# 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說有一個語法錯誤,這意味着腳本不滿足Python可以識別的結構。當我們觀察Python給出的錯誤的時候,它也告訴了我們它檢測出錯誤的位置。所以我們從那行開始 調試 我們的程序。

通過仔細的觀察,我們發現一個邏輯行被分成了兩個物理行,但是我們並沒有指明這兩個物理行屬於同一邏輯行。基本上,Python發現加法操作符(+)在那一邏輯行沒有任何操作數,因此它不知道該如何繼續。記住我們可以使用物理行尾的反斜槓來表示邏輯行在下一物理行繼續。所以,我們修正了程序。這被稱爲修訂

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'

這個程序現在工作了!讓我們看一下版本三中作出的實質性改進。我們使用raw_input函數得到用戶的註釋,然後通過len函數找出輸入的長度以檢驗用戶是否確實輸入了什麼東西。如果用戶只是按了回車(比如這只是一個慣例備份,沒有做什麼特別的修改),那麼我們就如之前那樣繼續操作。

然而,如果提供了註釋,那麼它會被附加到zip歸檔名,就在.zip擴展名之前。注意我們把註釋中的空格替換成下劃線——這是因爲處理這樣的文件名要容易得多。

對於大多數用戶來說,第四個版本是一個滿意的工作腳本了,但是它仍然有進一步改進的空間。比如,你可以在程序中包含 交互 程度——你可以用-v選項來使你的程序更具交互性。

另一個可能的改進是使文件和目錄能夠通過命令行直接傳遞給腳本。我們可以通過sys.argv列表來獲取它們,然後我們可以使用list類提供的extend方法把它們加到source列表中去。

我還希望有的一個優化是使用tar命令替代zip命令。這樣做的一個優勢是在你結合使用targzip命令的時候,備份會更快更小。如果你想要在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表示含在指定文件名列表中的文件會被排除在備份之外。例如,你可以在文件中指定*~,從而不讓備份包括所有以~結尾的文件。

最理想的創建這些歸檔的方法是分別使用zipfiletarfile。它們是Python標準庫的一部分,可以供你使用。使用這些庫就避免了使用os.system這個不推薦使用的函數,它容易引發嚴重的錯誤。
然而,我在本節中使用os.system的方法來創建備份,這純粹是爲了教學的需要。這樣的話,例子就可以簡單到讓每個人都能夠理解,同時也已經足夠用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章