目录
以下是關於在 Debian 系統上管理二進位制和文字資料的工具及其相關提示。
資料的安全和它的受控共享有如下幾個方面。
存檔檔案的建立
遠端儲存訪問
複製
跟蹤修改歷史
促進資料共享
防止未經授權的檔案訪問
檢測未經授權的檔案修改
這些可以通過使用工具集來實現。
存檔和壓縮工具
複製和同步工具
網路檔案系統
移動儲存媒介
安全 shell
認證體系
版本控制系統工具
雜湊演算法和加密工具
以下是 Debian 系統上可用的存檔和壓縮工具的預覽。
表 10.1. 存檔和壓縮工具列表
軟件包 | 流行度 | 大小 | 副檔名 | 命令 | 描述 |
---|---|---|---|---|---|
tar
|
V:915, I:999 | 2770 |
.tar
|
tar(1) | 標準的歸檔工具(預設) |
cpio
|
V:409, I:998 | 989 |
.cpio
|
cpio(1) | Unix System V 風格的歸檔器,與 find(1) 一起使用 |
binutils
|
V:191, I:707 | 89 |
.ar
|
ar(1) | 建立靜態庫的歸檔工具 |
fastjar
|
V:5, I:53 | 172 |
.jar
|
fastjar(1) | Java 歸檔工具(類似 zip) |
pax
|
V:16, I:45 | 175 |
.pax
|
pax(1) |
新的 POSIX 歸檔工具,介於 tar 和 cpio 之間
|
gzip
|
V:884, I:999 | 231 |
.gz
|
gzip(1), zcat(1), … | GNU LZ77 壓縮工具(預設) |
bzip2
|
V:198, I:942 | 184 |
.bz2
|
bzip2(1), bzcat(1), … | Burrows-Wheeler
block-sorting 壓縮工具有著比
gzip(1)
更高的壓縮率 (跟 gzip 有著相似的語法但速度比它慢)
|
lzma
|
V:4, I:51 | 141 |
.lzma
|
lzma(1) | LZMA 壓縮工具有著比 gzip(1) 更高的壓縮率(不推薦) |
xz-utils
|
V:432, I:956 | 515 |
.xz
|
xz(1), xzdec(1), … | XZ 壓縮工具有著比
bzip2(1)
更高的壓縮率(壓縮速度慢於 gzip 但是比 bzip2 快; LZMA 壓縮工具的替代品)
|
p7zip
|
V:78, I:360 | 934 |
.7z
|
7zr(1), p7zip(1) | 有著更高壓縮率的 7-zip 檔案歸檔器(LZMA 壓縮) |
p7zip-full
|
V:149, I:523 | 4407 |
.7z
|
7z(1), 7za(1) | 有著更高壓縮率的 7-Zip 檔案歸檔器(LZMA 壓縮和其他) |
lzop
|
V:6, I:48 | 97 |
.lzo
|
lzop(1) | LZO 壓縮工具有著比
gzip(1)
更高的壓縮和解壓縮速度 (跟 gzip 有著相似的語法但壓縮率比它低)
|
zip
|
V:52, I:429 | 608 |
.zip
|
zip(1) | InfoZip:DOS 歸檔器和壓縮工具 |
unzip
|
V:349, I:800 | 534 |
.zip
|
unzip(1) | InfoZIP:DOS 解檔器和解壓縮工具 |
![]() |
警告 |
---|---|
除非你知道將會發生什麼,否則不要設定 " |
![]() |
注意 |
---|---|
gzipped
tar(1)
歸檔器用於副檔名是 " |
![]() |
注意 |
---|---|
xz-compressed
tar(1)
歸檔器用於副檔名是 " |
![]() |
注意 |
---|---|
FOSS 工具,例如
tar(1),中的主流壓縮方法已經按如下所示的遷移:
|
![]() |
注意 |
---|---|
cp(1),scp(1) 和 tar(1) 工具可能並不適用於一些特殊的檔案。cpio(1) 工具的適用範圍是最廣的。 |
![]() |
注意 |
---|---|
cpio(1) 是被設計為與 find(1) 和其它命令一起使用,適合於建立備份指令碼的場景,因此,指令碼的檔案選擇部分能夠被獨立測試。 |
![]() |
注意 |
---|---|
Libreoffice 資料檔案的內部結構是 " |
![]() |
注意 |
---|---|
事實上跨平臺支援最好的存檔工具是 |
以下是 Debian 系統上的可用的簡單複製和備份工具的預覽。
表 10.2. 複製和同步工具列表
軟件包 | 流行度 | 大小 | 工具 | 功能 |
---|---|---|---|---|
coreutils
|
V:886, I:999 | 15016 | GNU cp | 複製本地檔案和目錄("-a" 引數實現遞迴) |
openssh-client
|
V:822, I:995 | 4147 | scp |
複製遠端檔案和目錄(客戶端,"-r " 引數實現遞迴)
|
openssh-server
|
V:684, I:811 | 870 | sshd | 複製遠端檔案和目錄(遠端伺服器) |
rsync
|
V:222, I:609 | 691 | - | 單向遠端同步和備份 |
unison
|
V:4, I:19 | 3452 | - | 雙向遠端同步和備份 |
在複製檔案的時候, rsync(8) 比其他工具提供了更多的特性。
差分傳輸演算法只會傳送原始檔與已存在的目標檔案之間的差異部分
快速檢查演算法 (預設) 會查詢大小或者最後的修改時間有變化的檔案
"--exclude
" 和 "--exclude-from
" 選項類似於
tar(1)
在源目錄中新增反斜槓的語法能夠避免在目標檔案中建立額外的目錄級別。
![]() |
提示 |
---|---|
在
cron(8)
下使用" |
![]() |
提示 |
---|---|
在 表 10.11 “版本控制系統工具列表” 中的版本控制系統 (VCS) 可以被認為是多路拷貝和同步工具。 |
以下是用不同的工具壓縮和解壓縮整個 "./source
" 目錄中的內容。
GNU tar(1):
$ tar -cvJf archive.tar.xz ./source $ tar -xvJf archive.tar.xz
或者,如下所示。
$ find ./source -xdev -print0 | tar -cvJf archive.tar.xz --null -F -
cpio(1):
$ find ./source -xdev -print0 | cpio -ov --null > archive.cpio; xz archive.cpio $ zcat archive.cpio.xz | cpio -i
如下是用不同的工具複製整個 "./source
" 目錄中的內容。
本地複製: "./source
" 目錄 → "/dest
" 目錄
遠端複製:本地主機上的 "./source" 目錄
→
"user@host.dom
" 主機上的 "/dest
" 目錄
rsync(8):
# cd ./source; rsync -aHAXSv . /dest # cd ./source; rsync -aHAXSv . user@host.dom:/dest
你能夠選擇使用“源目錄上的反斜槓”語法。
# rsync -aHAXSv ./source/ /dest # rsync -aHAXSv ./source/ user@host.dom:/dest
或者,如下所示。
# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . /dest # cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . user@host.dom:/dest
GNU cp(1) 和 openSSH scp(1):
# cd ./source; cp -a . /dest # cd ./source; scp -pr . user@host.dom:/dest
GNU tar(1):
# (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - ) # (cd ./source && tar cf - . ) | ssh user@host.dom '(cd /dest && tar xvfp - )'
cpio(1):
# cd ./source; find . -print0 | cpio -pvdm --null --sparse /dest
你能夠在所有包含 ".
" 的例子裡用 "foo
" 替代
".
",這樣就可以從 "./source/foo
" 目錄複製檔案到
"/dest/foo
" 目錄。
在所有包含 ".
" 的列子裡,你能夠使用絕對路徑
"/path/to/source/foo
" 來代替 ".
",這樣可以去掉
"cd ./source;
". 如下所示,這些檔案會根據工具的不同,拷貝到不同的位置。
"/dest/foo
":
rsync(8),
GNU
cp(1),
和
scp(1)
"/dest/path/to/source/foo
": GNU
tar(1),
和
cpio(1)
![]() |
提示 |
---|---|
rsync(8)
和 GNU
cp(1)
可以用 " |
find(1) 被用作從歸檔中篩選檔案也被用作拷貝命令 (參見第 10.1.3 节 “歸檔語法”和第 10.1.4 节 “複製語法”) 或者用於 xargs(1) (參見第 9.3.9 节 “使用檔案迴圈來重複一個命令”)。通過 find 的命令列引數能夠使其功能得到加強。
以下是 find(1)基本語法的總結。
find 條件引數的運算規則是從左到右。
一旦輸出是確定的,那麼運算就會停止。
“邏輯 OR" (由條件之間的 "-o
"
引數指定的)優先順序低於 "邏輯 AND" (由
"-a
" 引數指定或者條件之間沒有任何引數)。
”邏輯 NOT" (由條件前面的 "!
"
指定) 優先順序高於 “邏輯 AND”。
"-prune
" 總是返回邏輯 TRUE
並且如果這個目錄是存在的,將會搜尋除這個目錄以外的檔案。
"-name
" 選項匹配帶有 shell 萬用字元 (參見第 1.5.6 节 “Shell 萬用字元”) 的檔名但也匹配帶有類似 "*
" 和
"?
" 元字元的 .
"。(新的 POSIX 特性)
"-regex
" 匹配整個檔案路徑,預設採用 emacs 風格的 BRE (參見第 1.6.2 节 “正則表達式”)。
"-size
" 根據檔案大小來匹配 (值前面帶有 "+
"
號匹配更大的檔案,值前面帶有 "-
" 號匹配更小的檔案)
"-newer
" 引數匹配比引數名中指定的檔案還要新的檔案。
"-print0
" 引數總是返回邏輯 TRUE 並將完整檔名 (null
terminated) 列印到標準輸出裝置上。
如下是 find(1) 語法格式。
# find /path/to \ -xdev -regextype posix-extended \ -type f -regex ".*\.cpio|.*~" -prune -o \ -type d -regex ".*/\.git" -prune -o \ -type f -size +99M -prune -o \ -type f -newer /path/to/timestamp -print0
這些命令會執行如下動作。
查詢 "/path/to
" 下的所有檔案
限定全域性查詢的檔案系統並且使用的是 ERE (參見第 1.6.2 节 “正則表達式”)
通過停止處理的方式來排除匹配 ".*\.cpio
" 或 ".*~
"
正則表示式的檔案
通過停止處理的方式來排除匹配 ".*/\.git
" 正則表示式的目錄
通過停止處理的方式來排除比 99MB (1048576位元組單元) 更大的檔案
顯示檔名,滿足以上搜索條件並且比 "/path/to/timestamp
" 新的檔案
請留心以上例子中的 "-prune -o
" 排除檔案的習慣用法。
![]() |
注意 |
---|---|
對於非 Debian 系的 Unix-like 系統,有些引數可能不被
find(1)
命令所支援。在這種情況下,應該考慮調整匹配方法並用 " |
為重要的資料存檔尋找 儲存裝置 時,你應該注意它們的侷限性。對於小型的個人資料備份,我使用品牌公司的 CD-R 和 DVD-R 然後把它放在陰涼、乾燥、清潔的地方。(專業的一般使用磁帶存檔介質)
![]() |
注意 |
---|---|
防火安全是對於紙質文件來說的,大多數的計算機資料儲存媒介耐熱性比紙差。我經常依賴儲存在多個安全地點的加密拷貝。 |
網上(主要是來源於供應商資訊)可以檢視儲存介質的最大使用壽命。
大於100年:用墨水的無酸紙
100年:光碟儲存(CD/DVD,CD/DVD-R)
30年:磁帶儲存(磁帶,軟盤)
20年:相變光碟儲存(CD-RW)
這不包括由於人為導致的機械故障等等。
網上(主要來源於供應商資訊)可以檢視儲存介質的最大的寫次數。
大於250,000次:硬碟驅動器
大於10,000次:快閃記憶體
1,000次:CD/DVD-RW
1次:CD/DVD-R,紙
![]() |
小心 |
---|---|
這裡的儲存壽命和寫次數的資料不應該被用來決定任何用於關鍵資料的儲存媒介,請翻閱製造商提供的特定產品的說明。 |
![]() |
提示 |
---|---|
因為 CD/DVD-R 和 紙只能寫一次,它們從根本上阻止了因為重寫導致的資料意外丟失。這是優點! |
![]() |
提示 |
---|---|
如果你需要更快更頻繁的進行大資料備份,那麼通過高速網路連線的遠端主機上的硬碟來實現備份,可能是唯一可行的方法。 |
可移動儲存裝置可能是以下的任何一種。
數碼相機
數字音樂播放器
它們可以通過以下的方式來進行連線。
像 GNOME 和 KDE 這樣的現代桌面環境能夠在 "/etc/fstab
"
檔案中沒有匹配條目的時候,自動掛載這些可移動裝置。
![]() |
提示 |
---|---|
umount(8)
在自動掛載裝置的時候可能會帶有 " |
![]() |
提示 |
---|---|
只有當這些可移動裝置沒有在 " |
現代桌面環境下的掛載點被選為 "/media/<disk_label>
",它可以被如下所示的來定製。
FAT 格式的檔案系統使用 mlabel(1) 命令
ISO9660 檔案系統使用帶有 "-V
" 選項的
genisoimage(1)
命令
ext2/ext3/ext4 檔案系統使用帶有 "-L
" 選項的
tune2fs(1)
命令
![]() |
提示 |
---|---|
掛載時可能需要提供編碼選項(參見 第 8.4.6 节 “檔名編碼”)。 |
![]() |
提示 |
---|---|
在圖形介面選單上移除檔案系統,可能會移除它的動態裝置節點例如
" |
當你通過可移動儲存裝置與其他系統分享資料的時候,你應該先把它格式化為被兩種作業系統都支援的通用的 檔案系統。下面是檔案系統的列表。
表 10.3. 典型使用場景下可移動儲存裝置可選擇的檔案系統列表
檔案系統 | 典型使用場景描述 |
---|---|
FAT12 | 軟盤(<32MiB)上跨平臺的資料分享 |
FAT16 | 在小硬碟(<2GiB)上的跨平臺的資料分享 |
FAT32 | 在大硬碟(<8TiB,被 MS Windows95 OSR2 以上的作業系統所支援) 上的跨平臺的資料分享 |
NTFS | 在大硬碟類裝置上的跨平臺共享資料 (在 MS Windows NT 和後續版本原生支援;在 Linux 上,通過使用 FUSE 的 NTFS-3G 支援。) |
ISO9660 | 在 CD-R 和 DVD+/-R 上的跨平臺的靜態資料分享 |
UDF | CD-R 和 DVD+/-R (新)上的增量資料寫入 |
MINIX 檔案系統 | 軟盤上磁碟空間高利用率的 unix 檔案資料儲存 |
ext2 檔案系統 | 在裝有老舊 linux 系統的硬碟上的資料分享 |
ext3 檔案系統 | 在裝有老舊 linux 系統的硬碟上的資料分享 |
ext4 檔案系統 | 在裝有較新的 linux 系統的硬碟上的資料分享 |
![]() |
提示 |
---|---|
檢視第 9.8.1 节 “使用 dm-crypt/LUKS 加密移動磁碟”來獲得關於使用裝置級加密的跨平臺的資料共享的資訊。 |
FAT 檔案系統被絕大多數的現代作業系統支援,它對於通過可行動硬碟進行的資料交換是非常有用的。
當格式化像裝有 FAT 檔案系統的跨平臺資料共享的可移動裝置時,以下應該是保險的選擇。
用 fdisk(8),cfdisk(8) 或者 parted(8) 命令(參見第 9.5.2 节 “硬碟分割槽配置”)把它們格式化為單個的主分割槽並對把它做如下標記。
標記小於 2GB 的 FAT 裝置為 字元"6"。
標記更大的 FAT32 裝置為字元 "c"。
如下所示是用 mkfs.vfat(8) 命令格式化主分割槽的。
它的裝置名字,例如 "/dev/sda1
" 用於 FAT16 裝置
明確的選項和它的裝置名,例如 "-F 32 /dev/sda1
" 用於 FAT32 裝置
當使用 FAT 或 ISO9660 檔案系統分享資料時,如下是需要注意的安全事項。
用 tar(1),或cpio(1)命令壓縮檔案,目地是為了保留檔名,符號連結,原始的檔案許可權和檔案所有者資訊。
用 split(1) 命令把壓縮檔案分解成若干小於 2GiB的小檔案,使其免受檔案大小限制。
加密壓縮檔案保護其內容免受未經授權的訪問。
![]() |
注意 |
---|---|
因為 FAT 檔案系統的設計,最大的檔案大小為 |
![]() |
注意 |
---|---|
微軟系統本身並不建議在超過 200MB 的分割槽或者驅動器上使用 FAT。他們的 " Overview of FAT, HPFS, and NTFS File Systems 這篇文章突出顯示了微軟系統的缺點,例如低效的磁碟空間利用。當然了,我們在 Linux 系統上還是應該使用 ext4 檔案系統。 |
![]() |
提示 |
---|---|
有關檔案系統和訪問檔案系統的更多資訊,請參考 "Filesystems HOWTO"。 |
當使用網路來分享資料的時候,你應該使用通用的服務。這裡有一些提示。
表 10.4. 典型使用場景下可選擇的網路服務列表
網路服務 | 典型使用場景描述 |
---|---|
SMB/CIFS 用 Samba 掛載網路檔案系統 |
通過 “Microsoft Windows 網路” 分享檔案,參見
smb.conf(5)
和 官方 Samba 3.x.x 指導和參考手冊(The
Official Samba 3.x.x HOWTO and Reference Guide) 或
samba-doc 軟體包
|
NFS 用 Linux 核心掛載網路檔案系統 | 通過 “Unix/Linux 網路" 分享檔案,參見 exports(5) 和 Linux NFS-HOWTO |
HTTP 服務 | 在 web 伺服器/客戶端之間分享檔案 |
HTTPS 服務 | 在有加密的安全套接層 (SSL) 或者安全傳輸層 (TLS) 的網路伺服器/客戶端中分享檔案 |
FTP 服務 | 在 FTP 伺服器/客戶端之間分享檔案 |
儘管對於檔案分享來說,通過網路掛載檔案系統和傳輸檔案是相當方便的,但這可能是不安全的。它們的網路連線必須通過如下所示的加強安全性。
我們都熟知計算機有時會出問題,或者由於人為的錯誤導致系統和資料損壞。備份和恢復操作是成功的系統管理中非常重要的一部分。可能有一天你的電腦就會出問題。
![]() |
提示 |
---|---|
保持你的備份系統簡潔並且經常備份你的系統,有備份資料比你採用的備份方法的技術先進要重要的多。 |
有3個關鍵的因素決定實際的備份和恢復策略。
知道要備份和恢復什麼。
你自己建立的資料檔案:在 "~/
" 下的資料
你使用的應用程式建立的資料檔案:在 "/var/
" 下的資料(除了
"/var/cache/
","/var/run/
" 和
"/var/tmp/
")
系統配置檔案:在 "/etc/
” 下的資料
本地軟體:在 "/usr/local/
" 或 "/opt/
" 下的資料
系統安裝資訊:關鍵步驟 (分割槽,...) 的純文字備忘錄
驗證資料結果:通過實驗性的恢復操作來預先驗證
知道怎樣去備份和恢復。
安全的資料儲存:保護其免於覆蓋和系統故障
經常備份:有計劃的備份
冗餘備份:資料映象
傻瓜式操作:單個簡單命令備份
評估涉及的風險和成本。
評估資料丟失的損失
備份所需的資源:人力,硬體,軟體,…
資料丟失的方式及其可能性
![]() |
注意 |
---|---|
除非你知道自己做的是什麼,否則不要備份 |
至於安全的資料儲存,資料至少是應該在不同的磁碟分割槽上最好是在不同的磁碟和機器上,來承受檔案系統發生的損壞。重要的資料最好儲存在只能寫一次的媒介上例如 CD/DVD-R 來防止覆蓋事故。(參見 第 9.7 节 “二進位制資料” 怎樣在 shell 命令列寫入儲存媒介。GNOME 桌面圖形環境可以讓你輕鬆的通過選單:“位置 → CD/DVD 燒錄”來實現寫入操作。)
![]() |
注意 |
---|---|
當備份資料的時候,你可能希望停止一些應用程式的守護程序例如 MTA(參見第 6.3 节 “郵件傳輸代理 (MTA)”)。 |
![]() |
注意 |
---|---|
你應該格外小心地備份和恢復身份認證相關的資料檔案例如 " |
![]() |
注意 |
---|---|
如果你以使用者程序的方式執行 cron job,你必須儲存檔案到
" |
以下是 Debian 系統上值得注意的實用備份程式套件的列表。
表 10.5. 實用備份程式套件列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
dump
|
V:1, I:7 | 341 | 4.4 BSD dump(8) 和 restore(8) 命令用於 ext2/ext3/ext4 檔案系統 |
xfsdump
|
V:0, I:11 | 838 | 在 GNU/Linux 和 IRIX 上用 xfsdump(8) 和 xfsrestore(8) 命令來備份和恢復 XFS 檔案系統 |
backupninja
|
V:4, I:4 | 329 | 輕量的可擴充套件的 meta-backup 系統 |
bacula-common
|
V:10, I:19 | 2055 | Bacula: 網路資料備份,恢復和核查-常見的支援檔案 |
bacula-client
|
I:5 | 164 | Bacula: 網路資料備份,恢復和核查-客戶端元軟體包 |
bacula-console
|
V:1, I:7 | 65 | Bacula: 網路資料備份,恢復和核查-文字終端 |
bacula-server
|
I:2 | 164 | Bacula: 網路資料備份,恢復和核查-伺服器端元軟體包 |
amanda-common
|
V:1, I:2 | 9964 | Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(庫) |
amanda-client
|
V:1, I:2 | 1072 | Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(客戶端) |
amanda-server
|
V:0, I:0 | 1044 | Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(伺服器端) |
backup-manager
|
V:1, I:2 | 543 | 命令列備份工具 |
backup2l
|
V:1, I:1 | 113 | 用於可掛載媒介 (基於磁碟的) 的低維護的備份/恢復工具 |
backuppc
|
V:4, I:5 | 2232 | BackupPC 是用於備份 PC 機資料(基於磁碟)的高效能的企業級工具 |
duplicity
|
V:8, I:16 | 1538 | (遠端) 增量備份 |
flexbackup
|
V:0, I:0 | 242 | (遠端) 增量備份 |
rdiff-backup
|
V:9, I:18 | 704 | (遠端) 增量備份 |
restic
|
V:0, I:0 | 16046 | (遠端) 增量備份 |
rsnapshot
|
V:6, I:12 | 452 | (遠端) 增量備份 |
slbackup
|
V:0, I:0 | 146 | (遠端) 增量備份 |
備份工具有各自的專用的用途。
Mondo Rescue 是一個備份系統,它能夠方便的從備份 CD/DVD 等裝置中快速恢復整個系統,而不需要經過常規的系統安裝過程。
定期備份使用者資料,可以通過一個簡單的指令碼(第 10.2.2 节 “一個系統備份的指令碼例子”)和 cron(8) 來實現。
第 10.1.1 节 “存檔和壓縮工具” 和 第 10.1.2 节 “複製和同步工具” 描述的基礎工具能夠通過自定義指令碼來幫助系統備份。這些指令碼的功能可以通過如下的工具來增強。
restic
軟體包能夠增量備份(遠端)。
rdiff-backup
軟體包能夠增量備份(遠端)。
dump
軟體包用於高效增量的歸檔和恢復整個檔案系統。
![]() |
提示 |
---|---|
參見 " |
對於執行 unstable
套件的個人 Debian
桌面系統來說,只需要保護個人資料和關鍵資料。我不管怎樣每年都會重新安裝一次系統。因此沒理由去備份整個系統或者安裝全功能的備份實用程式。
我使用簡單的指令碼來製作用於備份的壓縮檔案並用 GUI 介面把它燒寫到 CD/DVD 裡。以下是關於這個的指令碼例子。
#!/bin/sh -e # Copyright (C) 2007-2008 Osamu Aoki <osamu@debian.org>, Public Domain BUUID=1000; USER=osamu # UID and name of a user who accesses backup files BUDIR="/var/backups" XDIR0=".+/Mail|.+/Desktop" XDIR1=".+/\.thumbnails|.+/\.?Trash|.+/\.?[cC]ache|.+/\.gvfs|.+/sessions" XDIR2=".+/CVS|.+/\.git|.+/\.svn|.+/Downloads|.+/Archive|.+/Checkout|.+/tmp" XSFX=".+\.iso|.+\.tgz|.+\.tar\.gz|.+\.tar\.bz2|.+\.cpio|.+\.tmp|.+\.swp|.+~" SIZE="+99M" DATE=$(date --utc +"%Y%m%d-%H%M") [ -d "$BUDIR" ] || mkdir -p "BUDIR" umask 077 dpkg --get-selections \* > /var/lib/dpkg/dpkg-selections.list debconf-get-selections > /var/cache/debconf/debconf-selections { find /etc /usr/local /opt /var/lib/dpkg/dpkg-selections.list \ /var/cache/debconf/debconf-selections -xdev -print0 find /home/$USER /root -xdev -regextype posix-extended \ -type d -regex "$XDIR0|$XDIR1" -prune -o -type f -regex "$XSFX" -prune -o \ -type f -size "$SIZE" -prune -o -print0 find /home/$USER/Mail/Inbox /home/$USER/Mail/Outbox -print0 find /home/$USER/Desktop -xdev -regextype posix-extended \ -type d -regex "$XDIR2" -prune -o -type f -regex "$XSFX" -prune -o \ -type f -size "$SIZE" -prune -o -print0 } | cpio -ov --null -O $BUDIR/BU$DATE.cpio chown $BUUID $BUDIR/BU$DATE.cpio touch $BUDIR/backup.stamp
這是一個用 root 許可權執行的指令碼例子。
我建議你按照如下所示的去更改和執行這個指令碼。
編輯這個指令碼使其能夠覆蓋到你所有的重要資料(參見第 10.1.5 节 “查詢檔案的語法” 和 第 10.2 节 “備份和恢復”)。
用 "find ...-newer $BUDIR/backup.stamp -print0
" 替代
"find ...-print0
" 來實現增量備份。
為保險起見,使用 scp(1) 或 rsync(1) 命令來備份檔案到遠端 或者把它們燒寫到 CD/DVD 裡。(我使用 GNOME 桌面 GUI 來燒寫 CD/DVD。參見 第 12.1.8 节 “zenity 的 shell 指令碼案例” 來獲得更多的資訊。)
把事情簡單化!
![]() |
提示 |
---|---|
你能夠用 " |
對於目錄樹下面的資料集,"cp -a
" 命令可以實現常規備份。
對於類似 "/var/cache/apt/packages/
" 目錄下面的大量不可覆蓋的靜態資料集,使用
"cp -al
" 命令來建立硬連結是一種替代常規備份的方式,這樣可以高效的利用磁碟空間。
以下是一個用於資料備份的名為 bkup
的複製指令碼。它把當前目錄下的所有 (non-VCS)
檔案複製到父目錄下的指定目錄中或者遠端主機上。
#!/bin/sh -e # Copyright (C) 2007-2008 Osamu Aoki <osamu@debian.org>, Public Domain fdot(){ find . -type d \( -iname ".?*" -o -iname "CVS" \) -prune -o -print0;} fall(){ find . -print0;} mkdircd(){ mkdir -p "$1";chmod 700 "$1";cd "$1">/dev/null;} FIND="fdot";OPT="-a";MODE="CPIOP";HOST="localhost";EXTP="$(hostname -f)" BKUP="$(basename $(pwd)).bkup";TIME="$(date +%Y%m%d-%H%M%S)";BU="$BKUP/$TIME" while getopts gcCsStrlLaAxe:h:T f; do case $f in g) MODE="GNUCP";; # cp (GNU) c) MODE="CPIOP";; # cpio -p C) MODE="CPIOI";; # cpio -i s) MODE="CPIOSSH";; # cpio/ssh t) MODE="TARSSH";; # tar/ssh r) MODE="RSYNCSSH";; # rsync/ssh l) OPT="-alv";; # hardlink (GNU cp) L) OPT="-av";; # copy (GNU cp) a) FIND="fall";; # find all A) FIND="fdot";; # find non CVS/ .???/ x) set -x;; # trace e) EXTP="${OPTARG}";; # hostname -f h) HOST="${OPTARG}";; # user@remotehost.example.com T) MODE="TEST";; # test find mode \?) echo "use -x for trace." esac; done shift $(expr $OPTIND - 1) if [ $# -gt 0 ]; then for x in $@; do cp $OPT $x $x.$TIME; done elif [ $MODE = GNUCP ]; then mkdir -p "../$BU";chmod 700 "../$BU";cp $OPT . "../$BU/" elif [ $MODE = CPIOP ]; then mkdir -p "../$BU";chmod 700 "../$BU" $FIND|cpio --null --sparse -pvd ../$BU elif [ $MODE = CPIOI ]; then $FIND|cpio -ov --null | ( mkdircd "../$BU"&&cpio -i ) elif [ $MODE = CPIOSSH ]; then $FIND|cpio -ov --null|ssh -C $HOST "( mkdircd \"$EXTP/$BU\"&&cpio -i )" elif [ $MODE = TARSSH ]; then (tar cvf - . )|ssh -C $HOST "( mkdircd \"$EXTP/$BU\"&& tar xvfp - )" elif [ $MODE = RSYNCSSH ]; then rsync -aHAXSv ./ "${HOST}:${EXTP}-${BKUP}-${TIME}" else echo "Any other idea to backup?" $FIND |xargs -0 -n 1 echo fi
如上只是一個範例。在你自己使用指令碼之前,請閱讀此指令碼並且修改它。
![]() |
提示 |
---|---|
我把 |
![]() |
提示 |
---|---|
如果是要製作原始檔樹或者配置檔案樹的快照歷史的話,使用 git(7) (參見第 10.6.5 节 “記錄配置歷史的 Git”) 是更簡便並且也是空間高效的。 |
資料安全基礎設施是資料加密,訊息摘要和簽名工具的結合。
表 10.6. 資料安全基礎工具列表
軟件包 | 流行度 | 大小 | 命令 | 說明 |
---|---|---|---|---|
gnupg
|
V:698, I:998 | 693 | gpg(1) | GNU 隱私衛士 - OpenPGP 加密和簽名工具 |
gpgv
|
V:881, I:999 | 807 | gpgv(1) | GNU 隱私衛士 - 簽名驗證工具 |
paperkey
|
V:0, I:2 | 55 | paperkey(1) | 從 OpenPGP 私鑰裡面,僅僅匯出私密資訊 |
cryptsetup
|
V:39, I:80 | 360 | cryptsetup(8), … | dm-crypto 塊裝置加密支援 LUKS 工具 |
ecryptfs-utils
|
V:6, I:9 | 396 | ecryptfs(7), … | ecryptfs 堆疊檔案系統加密工具 |
coreutils
|
V:886, I:999 | 15016 | md5sum(1) | 計算與校驗 MD5 訊息摘要 |
coreutils
|
V:886, I:999 | 15016 | sha1sum(1) | 計算與校驗 SHA1 訊息摘要 |
openssl
|
V:794, I:990 | 1303 | openssl(1ssl) |
使用 "openssl dgst " (OpenSSL)計算資訊摘要
|
參見 第 9.8 节 “資料加密提示” 的 dm-crypto 和 ecryptfs,它們通過 Linux 核心模組實現了自動資料加密架構。
如下是 GNU 隱私衛士 基本的金鑰管理命令。
表 10.7. GNU 隱私衛士金鑰管理命令的列表
命令 | 說明 |
---|---|
gpg --gen-key
|
生成一副新的金鑰對 |
gpg --gen-revoke my_user_ID
|
生成 my_user_ID 的一份吊銷證書 |
gpg --edit-key user_ID
|
互動式的編輯金鑰,輸入 "help" 來獲得幫助資訊 |
gpg -o file --export
|
把所有的金鑰輸出到檔案 |
gpg --import file
|
從檔案匯入金鑰 |
gpg --send-keys user_ID
|
傳送 user_ID 的公鑰到公鑰伺服器 |
gpg --recv-keys user_ID
|
從公鑰伺服器下載 user_ID 的公鑰 |
gpg --list-keys user_ID
|
列出 user_ID 的所有金鑰 |
gpg --list-sigs user_ID
|
列出 user_ID 的簽字 |
gpg --check-sigs user_ID
|
檢查 user_ID 金鑰簽字 |
gpg --fingerprint user_ID
|
檢查 user_ID 的指紋 |
gpg --refresh-keys
|
更新本地金鑰 |
信任碼含義.
如下命令上傳我的 "1DD8D791
" 公鑰到主流的公鑰伺服器
"hkp://keys.gnupg.net
"。
$ gpg --keyserver hkp://keys.gnupg.net --send-keys 1DD8D791
預設良好的公鑰伺服器在 "~/.gnupg/gpg.conf
" (舊的位置在
"~/.gnupg/options
")檔案中設定,此檔案包含了以下資訊。
keyserver hkp://keys.gnupg.net
從鑰匙伺服器獲取無名鑰匙。
$ gpg --list-sigs --with-colons | grep '^sig.*\[User ID not found\]' |\ cut -d ':' -f 5| sort | uniq | xargs gpg --recv-keys
有一個錯誤在 OpenPGP 公鑰伺服器 (先前的版本
0.9.6),會將鍵中斷為 2 個以上的子鍵。新的 gnupg
(>1.2.1-2)
軟體包能夠處理這些中斷的子鍵。參見
gpg(1)
下的 "--repair-pks-subkey-bug
" 選項.
這裡有一些在檔案上使用 GNU 隱私衛士 命令的例子。
表 10.9. 在檔案上使用的 GNU 隱私衛士的命令列表
命令 | 說明 |
---|---|
gpg -a -s file
|
ASCII 封裝的簽名檔案 file.asc |
gpg --armor --sign file
|
同上 |
gpg --clearsign file
|
生成明文簽字資訊 |
gpg --clearsign file|mail foo@example.org
|
傳送一份明文簽字到 foo@example.org
|
gpg --clearsign --not-dash-escaped patchfile
|
明文簽名的補丁檔案 |
gpg --verify file
|
驗證明文檔案 |
gpg -o file.sig -b file
|
生成一份分離的簽字 |
gpg -o file.sig --detach-sig file
|
同上 |
gpg --verify file.sig file
|
使用 file.sig 驗證檔案 |
gpg -o crypt_file.gpg -r name -e file
|
公鑰加密,從檔案裡面獲取名字,生成二進位制的 crypt_file.gpg |
gpg -o crypt_file.gpg --recipient name --encrypt file
|
同上 |
gpg -o crypt_file.asc -a -r name -e file
|
公鑰加密,從檔案中獲取名字,生成 ASCII 封裝的 crypt_file.asc |
gpg -o crypt_file.gpg -c file
|
將檔案對稱加密到 crypt_file.gpg |
gpg -o crypt_file.gpg --symmetric file
|
同上 |
gpg -o crypt_file.asc -a -c file
|
對稱加密,從檔案到 ASCII 封裝的 crypt_file.asc |
gpg -o file -d crypt_file.gpg -r name
|
解密 |
gpg -o file --decrypt crypt_file.gpg
|
同上 |
增加下面內容到 "~/.muttrc
",在自動啟動時,避免一個慢的 GnuPG,在索引選單中按
"S
" 來允許它使用。
macro index S ":toggle pgp_verify_sig\n" set pgp_verify_sig=no
gnupg
外掛可以讓你對副檔名為 ".gpg
",
".asc
", 和 ".ppg
"的檔案可靠的執行 GnuPG.
# aptitude install vim-scripts vim-addon-manager $ vim-addons install gnupg
md5sum(1) 提供了製作摘要檔案的一個工具,它使用 rfc1321 裡的方式製作摘要檔案.
$ md5sum foo bar >baz.md5 $ cat baz.md5 d3b07384d113edec49eaa6238ad5ff00 foo c157a79031e1c40f85931829bc5fc552 bar $ md5sum -c baz.md5 foo: OK bar: OK
![]() |
注意 |
---|---|
MD5 校驗和的 CPU 計算強度是比 GNU Privacy Guard (GnuPG) 加密簽名要少的.在通常情況下,只有頂級的摘要檔案才需要加密簽名來確保資料完整性. |
這裡有許多原始碼合併工具。如下的是我感興趣的工具。
表 10.10. 原始碼合併工具列表
軟件包 | 流行度 | 大小 | 命令 | 說明 |
---|---|---|---|---|
diffutils
|
V:866, I:982 | 1394 | diff(1) | 逐行比較兩個檔案 |
diffutils
|
V:866, I:982 | 1394 | diff3(1) | 逐行比較和合並三個檔案 |
vim
|
V:117, I:396 | 2507 | vimdiff(1) | 在 vim 中並排比較兩個檔案 |
patch
|
V:132, I:837 | 216 | patch(1) | 給原檔案打補丁 |
dpatch
|
V:1, I:15 | 191 | dpatch(1) | 管理 Debian 軟體包的系列補丁 |
diffstat
|
V:19, I:187 | 70 | diffstat(1) | 通過 diff 生成一個改變柱狀圖 |
patchutils
|
V:19, I:180 | 223 | combinediff(1) | 從兩個增量補丁建立一個積累補丁 |
patchutils
|
V:19, I:180 | 223 | dehtmldiff(1) | 從一個 HTML 頁面提取出一個 diff |
patchutils
|
V:19, I:180 | 223 | filterdiff(1) | 從一個 diff 檔案裡面提取或者排除 diff 檔案 |
patchutils
|
V:19, I:180 | 223 | fixcvsdiff(1) | 修復由 CVS patch(1) 錯誤建立的 diff 檔案 |
patchutils
|
V:19, I:180 | 223 | flipdiff(1) | 交換兩個補丁的順序 |
patchutils
|
V:19, I:180 | 223 | grepdiff(1) | 顯示哪些檔案是由匹配正則表示式的補丁修改 |
patchutils
|
V:19, I:180 | 223 | interdiff(1) | 顯示在兩個統一格式 diff 檔案(基於同一個檔案的兩個不同 diff 檔案)之間的差異 |
patchutils
|
V:19, I:180 | 223 | lsdiff(1) | 顯示哪些檔案由補丁修改 |
patchutils
|
V:19, I:180 | 223 | recountdiff(1) | 重新計算通用內容 diff 檔案的數量和偏移 |
patchutils
|
V:19, I:180 | 223 | rediff(1) | 修復手工編輯 diff 檔案的數量和偏移 |
patchutils
|
V:19, I:180 | 223 | splitdiff(1) | 隔離出增量補丁 |
patchutils
|
V:19, I:180 | 223 | unwrapdiff(1) | 識別已經被分詞的補丁 |
wiggle
|
V:0, I:0 | 166 | wiggle(1) | 應用被拒絕的補丁 |
quilt
|
V:3, I:43 | 711 | quilt(1) | 管理系列補丁 |
meld
|
V:15, I:41 | 3116 | meld(1) | 比較和移植檔案(GTK) |
dirdiff
|
V:0, I:2 | 144 | dirdiff(1) | 顯示目錄樹之間的不同並移植改變 |
docdiff
|
V:0, I:0 | 573 | docdiff(1) | 逐詞逐字的比較兩個檔案 |
imediff2
|
V:0, I:0 | 34 | imediff2(1) | 全屏交付式雙向移植工具 |
makepatch
|
V:0, I:0 | 102 | makepatch(1) | 生成擴充套件補丁檔案 |
makepatch
|
V:0, I:0 | 102 | applypatch(1) | 應用擴充套件補丁檔案 |
wdiff
|
V:5, I:81 | 643 | wdiff(1) | 在文字檔案中,顯示單詞的不同 |
下面的操作,匯出兩個原始檔的不同,並根據檔案的位置,建立通用 diff 檔案"file.patch0
" 或
"file.patch1
".
$ diff -u file.old file.new > file.patch0 $ diff -u old/file new/file > file.patch1
diff 檔案(通常被叫作 patch 補丁檔案),用於傳送一個程式更新。通過下面的方式,接收到的部分,應用這個更新到其它檔案。
$ patch -p0 file < file.patch0 $ patch -p1 file < file.patch1
如下是 Debian 系統上可用的版本控制系統(VCS) 的摘要。
![]() |
注意 |
---|---|
如果是剛接觸版本控制系統,你應該從 git 入門,git 人氣日益高漲。 |
表 10.11. 版本控制系統工具列表
軟件包 | 流行度 | 大小 | 工具 | VCS 型別 | 描述 |
---|---|---|---|---|---|
cssc
|
V:0, I:2 | 1979 | CSSC | 本地 | Unix SCCS (過時)的克隆 |
rcs
|
V:3, I:23 | 539 | RCS | 本地 | "比 Unix SCCS 做的好" |
cvs
|
V:6, I:57 | 4597 | CVS | 遠端 | 以前的遠端 VCS 標準 |
subversion
|
V:30, I:150 | 4678 | Subversion | 遠端 | ”比 CVS 做的好“,遠端 VCS 的新標準 |
git
|
V:271, I:438 | 32161 | Git | 分散式 | 用 C 寫的快速 DVCS (被 Linux 核心和其他專案使用) |
mercurial
|
V:11, I:62 | 548 | Mercurial | 分散式 | mercurial 主要是用 Python 寫的還有一部分是 C 寫的 |
bzr
|
V:4, I:23 | 73 | Bazaar | 分散式 |
受 tla 啟發並且是用 Python 寫的 DVCS (被 Ubuntu 使用)
|
darcs
|
V:0, I:8 | 31349 | Darcs | 分散式 | 有智慧代數補丁的 DVCS(慢) |
tla
|
V:0, I:7 | 1011 | GNU arch | 分散式 | 主要由 Tom Lord 寫的 DVCS (成為歷史的) |
monotone
|
V:0, I:0 | 5815 | Monotone | 分散式 | 用 C++ 寫的 DVCS |
tkcvs
|
V:0, I:1 | 1498 | CVS, … | 遠端 | VCS (CVS,Subversion,RCS) 儲存庫樹的圖形介面顯示 |
gitk
|
V:7, I:50 | 1474 | Git | 分散式 | VCS (Git) 儲存庫樹的圖形介面顯示 |
VCS 有時被認為是修訂控制系統 (RCS), 或者是軟體配置管理程式 (SCM)。
像 Git 這樣的分散式 VCS 是現在正在使用的工具。參加那些已經存在的開源軟體的開發活動,掌握 CVS 和 Subversion 仍然是有用的。
通過 Debian Alioth service,Debian 能夠提供免費的幾乎所有的 VCS 服務。在 http://wiki.debian.org/Alioth 能找到它的說明文件。
這裡有一些關於建立共享訪問 VCS 歸檔的基礎知識。
使用 "umask 002
" (參見 第 1.2.4 节 “控制新建檔案的許可權:umask”)
使得所有的 VCS 歸檔檔案屬於一個相關的組
能夠在所有的 VCS 歸檔目錄設定組 ID(類似 BSD 的檔案建立方案,參見第 1.2.3 节 “文件系統權限”)
使得屬於這個組的使用者能夠共享 VCS 歸檔
這裡有原生 VCS 命令的簡單比較來提供大圖概要。典型的命令序列需要選項和引數。
表 10.12. 本地 VCS 命令比較
Git | CVS | Subversion | 功能 |
---|---|---|---|
git init
|
cvs init
|
svn create
|
建立(本地)儲存庫 |
- |
cvs login
|
- | 登入遠端儲存庫 |
git clone
|
cvs co
|
svn co
|
簽出遠端儲存庫到本地工作目錄樹 |
git pull
|
cvs up
|
svn up
|
通過合併遠端儲存庫來更新工作目錄樹 |
git add .
|
cvs add
|
svn add
|
把工作目錄樹中的檔案新增到 VCS |
git rm
|
cvs rm
|
svn rm
|
從 VCS 中移除工作目錄樹中的檔案 |
- |
cvs ci
|
svn ci
|
提交改變到遠端儲存庫 |
git commit -a
|
- | - | 提交改變到本地儲存庫 |
git push
|
- | - | 通過本地儲存庫來更新遠端儲存庫 |
git status
|
cvs status
|
svn status
|
從 VCS 中顯示工作目錄樹的狀態 |
git diff
|
cvs diff
|
svn diff
|
比較<參考儲存庫>和<工作目錄樹>的差異 |
git repack -a -d; git prune
|
- | - | 重新打包本地倉庫到一個單獨的包 |
gitk
|
tkcvs
|
tkcvs
|
VCS 儲存庫樹的圖形介面顯示 |
![]() |
小心 |
---|---|
從命令列通過 " |
![]() |
提示 |
---|---|
如果有一個可執行檔案 |
![]() |
提示 |
---|---|
例如 tkcvs(1) 和 gitk(1) 這樣的圖形介面工具有助於追蹤檔案的修改歷史。許多公共的歸檔提供的用於瀏覽它們的儲存庫的 web 介面同樣是很有用的。 |
![]() |
提示 |
---|---|
Git 能夠直接在不同的 VCS 倉庫上工作,比如說 CVS 和 Subversion 提供的倉庫, 通過
|
![]() |
提示 |
---|---|
Git 中的有些命令在 CVS 和 Subversion 中並沒有對應的命令:"fetch","rebase","cherry-pick", … |
Git 可以用來做本地和遠程源代碼管理的任何事情。這意味着,你能夠在本地記錄源代碼修改,而不是必須要和遠程倉庫有網絡連接。
你可以在 "~/.gitconfig
" 裏面設置幾個 Git
接下來需要使用的全局配置,比如說你的名字和電子郵件地址。
$ git config --global user.name "姓名" $ git config --global user.email 電子郵件地址
如果你習慣使用 CVS 或 Subversion 命令,你也許希望設置如下幾個命令別名。
$ git config --global alias.ci "commit -a" $ git config --global alias.co checkout
你能夠通過如下方式檢查你的整體組態。
$ git config --global --list
看下面。
man 手冊: git(1)
(/usr/share/doc/git-doc/git.html
)
Git 用戶手冊
(/usr/share/doc/git-doc/user-manual.html
)
git 介紹教程
(/usr/share/doc/git-doc/gittutorial.html
)
git 介紹教程:第二部
(/usr/share/doc/git-doc/gittutorial-2.html
)
GIT 每一天 20個左右的命令
(/usr/share/doc/git-doc/everyday.html
)
CVS 用戶用 git
(/usr/share/doc/git-doc/gitcvs-migration.html
)
描述了怎樣搭建服務,以及如何把老的數據從 CVS 遷移到 Git。
Git 魔術
(/usr/share/doc/gitmagic/html/index.html
)
git-gui(1) 和 gitk(1) 命令使 Git 變得非常容易使用。
![]() |
警告 |
---|---|
不要使用帶空格的標簽字符串。即使一些工具,如
gitk(1)
允許你使用它,但會阻礙其它 |
即使你的上游使用不同的版本控制系統,使用 git(1) 作爲本地活動的版本控制系統,仍然是一個好的主意,因爲 git 可以讓你在沒有上遊網絡連接的情況下,管理你的本地源代碼樹拷貝。這裏有一些 git(1) 使用的包和命令。
表 10.13. git 相關包和命令列表
軟件包 | 流行度 | 大小 | 命令 | 說明 |
---|---|---|---|---|
git-doc
|
I:19 | 10603 | N/A | Git 官方文檔 |
gitmagic
|
I:1 | 719 | N/A | "Git 魔術",易於理解的 Git 手冊 |
git
|
V:271, I:438 | 32161 | git(7) | Git 快速、可擴展、分佈式的版本控制系統 |
gitk
|
V:7, I:50 | 1474 | gitk(1) | 有歷史功能的 Git 圖形倉庫瀏覽器 |
git-gui
|
V:2, I:29 | 2201 | git-gui(1) | Git 圖形界面(無歷史功能) |
git-svn
|
V:2, I:28 | 986 | git-svnimport(1) | 從 Subversion 導出數據,導入到 Git |
git-svn
|
V:2, I:28 | 986 | git-svn(1) | 在 Subversion 和 Git 之間提供雙向操作 |
git-cvs
|
V:0, I:13 | 1107 | git-cvsimport(1) | 從 CVS 導出數據,導入到 Git |
git-cvs
|
V:0, I:13 | 1107 | git-cvsexportcommit(1) | 從 Git 中檢出一個 CVS 的提交 |
git-cvs
|
V:0, I:13 | 1107 | git-cvsserver(1) | Git 的 CVS 服務模擬器 |
git-email
|
V:0, I:13 | 791 | git-send-email(1) | 從 Git 用電子郵件發送收集到的補丁 |
stgit
|
V:0, I:1 | 1535 | stg(1) | 封裝的 git (Python) |
git-buildpackage
|
V:1, I:12 | 3850 | git-buildpackage(1) | 用 Git 自動製作 Debian 包 |
guilt
|
V:0, I:0 | 146 | guilt(7) | 封裝的 git (SH/AWK/SED/…) |
![]() |
提示 |
---|---|
在
git(1)
下,你在本地分支下進行了許多提交,稍後你可以使用 " |
![]() |
提示 |
---|---|
當你想要回到一個乾淨的工作目錄,並且不丟失工作目錄當前的狀態,你可以使用 " |
你可以把 "svn+ssh://svn.example.org/project/module/trunk
" 的
Subversion 典藏所檢出到在地 Git 典藏所的 "./dest
" 並把修改提交回 Subversion
典藏所。例如:
$ git svn clone -s -rHEAD svn+ssh://svn.example.org/project dest $ cd dest ... 進行修改 $ git commit -a ... 繼續在本地用 git 工作 $ git svn dcommit
![]() |
提示 |
---|---|
使用 " |
你可以使用 Git
工具來手工記錄按時間先後順序的配置歷史。這裏是一個例子,讓你練習記錄"/etc/apt/
" 內容。
$ cd /etc/apt/ $ sudo git init $ sudo chmod 700 .git $ sudo git add . $ sudo git commit -a
提交配置,描述此次提交。
對配置文件進行修改。
$ cd /etc/apt/ $ sudo git commit -a
提交配置,說明提交,繼續你的工作。
$ cd /etc/apt/ $ sudo gitk --all
你有全部的配置歷史。
![]() |
注意 |
---|---|
sudo(8)
是需要用於配置數據文件,任意文件權限的情況。 對於普通用戶的配置數據,你需要省略 |
![]() |
注意 |
---|---|
在上面例子裏的 " |
![]() |
提示 |
---|---|
要更加完整的建立配置歷史記錄,請參閱 |
看下面。
cvs(1)
"/usr/share/doc/cvs/html-cvsclient
"
"/usr/share/doc/cvs/html-info
"
"/usr/share/doc/cvsbook
"
"info cvs
"
如下的配置將只允許 "src
" 組的成員向 CVS 儲存庫提交修改 ,只允許
"staff
" 組的成員管理 CVS,這樣可以減少出錯的機會。
# cd /var/lib; umask 002; mkdir cvs # export CVSROOT=/srv/cvs/project # cd $CVSROOT # chown root:src . # chmod 2775 . # cvs -d $CVSROOT init # cd CVSROOT # chown -R root:staff . # chmod 2775 . # touch val-tags # chmod 664 history val-tags # chown root:src history val-tags
![]() |
提示 |
---|---|
你可以改變 " |
預設的 CVS 儲存庫由 "$CVSROOT
" 指定。如下將建立用於本地訪問的
"$CVSROOT
"。
$ export CVSROOT=/srv/cvs/project
許多公共 CVS 伺服器可以通過 pserver 服務用 "anonymous
"
賬戶遠端只讀訪問。例如,Debian 網站的內容是 webwml
project 通過 Debian alioth 服務中的 CVS 來維護。如下將建立用於遠端訪問 CVS 儲存庫的
"$CVSROOT
"。
$ export CVSROOT=:pserver:anonymous@anonscm.debian.org:/cvs/webwml $ cvs login
![]() |
注意 |
---|---|
因為 pserver 容易被竊聽攻擊並且是不安全的,所以寫訪問通常是被伺服器管理員禁用的。 |
如下所示將建立 webwml project 使用 SSH 遠端訪問 CVS
儲存庫所需的 "$CVS_RSH
" 和 "$CVSROOT
"。
$ export CVS_RSH=ssh $ export CVSROOT=:ext:account@cvs.alioth.debian.org:/cvs/webwml
你也可以使用 SSH 的公鑰認證,這能夠去除遠端密碼提示。
按如下所示建立 "~/path/to/module1
" 路徑下的新的本地源目錄樹。
$ mkdir -p ~/path/to/module1; cd ~/path/to/module1
把檔案新增到 "~/path/to/module1
" 下的新的本地源目錄樹。
使用如下的引數把檔案匯入到 CVS。
模組名: "module1
"
提供商標籤: "Main-branch
" (用於整個分支的標籤)
釋出標籤: "Release-initial
" (用於特定釋出版本的標籤)
$ cd ~/path/to/module1 $ cvs import -m "Start module1" module1 Main-branch Release-initial $ rm -Rf . # optional
CVS 不會覆蓋當前的儲存庫檔案,只是用另外的檔案來替代它。因此,儲存庫目錄的寫許可權是很重要的。儲存庫位於
"/srv/cvs/project
" 的
"module1
",對於其下的每一個新模組而言,如果需要的話執行如下所示的來確保這種情況。
# cd /srv/cvs/project # chown -R root:src module1 # chmod -R ug+rwX module1 # chmod 2775 module1
這裡有一個 CVS 典型工作流的例子。
按如下所示檢視 "$CVSROOT
" 所指的 CVS 專案上所有可用的模組。
$ cvs rls CVSROOT module1 module2 ...
按如下所示簽出 "module1
" 到預設的目錄 "./module1
"。
$ cd ~/path/to $ cvs co module1 $ cd module1
按需修改裡面的內容。
通過如下所示的命令來檢查改變,其作用相當於使用 "diff -u [repository] [local]
"。
$ cvs diff -u
你發現自己改壞了 "file_to_undo
" 檔案,而其他的檔案都是好的。
按如下所示用 CVS 中的原始副本覆蓋 "file_to_undo
" 檔案。
$ cvs up -C file_to_undo
按如下所示把更新了的本地源目錄樹儲存到 CVS。
$ cvs ci -m "Describe change"
按如下建立並新增 "file_to_add
" 檔案到 CVS。
$ vi file_to_add $ cvs add file_to_add $ cvs ci -m "Added file_to_add"
按如下所示合併 CVS 中的最新版本。
$ cvs up -d
當心以 "C filename
" 開頭的行,這意味著衝突的改變。
檢視 ".#filename.version
" 中未經修改的程式碼。
查詢檔案中的 "<<<<<<<
" 和
">>>>>>>
" 來獲得衝突的改變的資訊。
按需更改檔案來解決衝突。
按如下所示新增一個釋出標籤 "Release-1
"。
$ cvs ci -m "last commit for Release-1" $ cvs tag Release-1
繼續編輯檔案。
按如下所示移除釋出分支 "Release-1
"。
$ cvs tag -d Release-1
按如下所示把改變簽入到 CVS。
$ cvs ci -m "real last commit for Release-1"
按如下所示給已經更新了的 CVS 主幹中的 HEAD 重新新增 "Release-1
" 釋出標籤。
$ cvs tag Release-1
按如下所示從 "Release-initial
" 標籤指向的初始版本中建立一個帶有粘性標籤的
"Release-initial-bugfixes
" 分支,並把它簽出到
"~/path/to/old
" 目錄。
$ cvs rtag -b -r Release-initial Release-initial-bugfixes module1 $ cd ~/path/to $ cvs co -r Release-initial-bugfixes -d old module1 $ cd old
![]() |
提示 |
---|---|
使用 " |
在基於原始版本的有 "Release-initial-bugfixes
" 粘性標籤的本地源目錄樹上工作。
獨自在 "Release-initial-bugfixes
" 分支上工作...直到有其他人加入到此分支。
當要建立新的目錄時,按如下所示同步其他人在此分支上對檔案所做的修改。
$ cvs up -d
按需更改檔案來解決衝突。
按如下所示把改變簽入到 CVS。
$ cvs ci -m "checked into this branch"
按如下所示更新本地目錄樹為主幹的最新版本,同時移除粘性標籤 ("-A
") 並且不使用關鍵字擴充套件
("-kk
")。
$ cvs up -d -kk -A
按如下所示通過合併 "Release-initial-bugfixes
"
分支並且不使用關鍵字擴充套件的方式來更新本地目錄樹 (內容為主幹中的最新版本)。
$ cvs up -d -kk -j Release-initial-bugfixes
用編輯器來解決衝突。
按如下所示把改變簽入到 CVS。
$ cvs ci -m "merged Release-initial-bugfixes"
按如下所示建立歸檔。
$ cd .. $ mv old old-module1-bugfixes $ tar -cvzf old-module1-bugfixes.tar.gz old-module1-bugfixes $ rm -rf old-module1-bugfixes
![]() |
提示 |
---|---|
" |
![]() |
提示 |
---|---|
你可以通過形如 " |
按如下所示往 CVS 專案 (本地伺服器) 裡新增 "mx
" 模組別名。
$ export CVSROOT=/srv/cvs/project $ cvs co CVSROOT/modules $ cd CVSROOT $ echo "mx -a module1" >>modules $ cvs ci -m "Now mx is an alias for module1" $ cvs release -d .
按如下所示,你可以從 CVS 中籤出 "module1
" (別名為:
"mx
") 到 "new
" 目錄。
$ cvs co -d new mx $ cd new
![]() |
注意 |
---|---|
為了執行上述步驟,你應當有合適的檔案許可權。 |
Subversion 是替代舊的 CVS 的近代版本控制系統。除了標籤和分支以外,它也擁有 CVS 的絕大多數特性。
你需要安裝 subversion
,libapache2-svn
和
subversion-tools
軟體包來搭建 Subversion 伺服器。
subversion
軟體包通常不會自動建立儲存庫,所以你必須手動搭建它。儲存庫可能的位置是在
"/srv/svn/project
"。
按如下所示建立目錄。
# mkdir -p /srv/svn/project
按如下所示建立儲存庫資料庫。
# svnadmin create /srv/svn/project
如果只是用 Apache2 伺服器訪問 Subversion 儲存庫,你只需按如下所示的使儲存庫只是對於 WWW 伺服器是可寫的。
# chown -R www-data:www-data /srv/svn/project
在 "/etc/apache2/mods-available/dav_svn.conf
" 中新增 (或取消註釋)
如下所示的來允許通過使用者認證訪問儲存庫。
<Location /project> DAV svn SVNPath /srv/svn/project AuthType Basic AuthName "Subversion repository" AuthUserFile /etc/subversion/passwd <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
用如下所示的命令建立使用者認證檔案。
# htpasswd2 -c /etc/subversion/passwd some-username
重啟 Apache2。
通過 "http://localhost/project
" 和
"http://example.com/project
" URL 來訪問
svn(1)
中的 Subversion 儲存庫(假設你的 web 伺服器的 URL 為
"http://example.com/
")。
如下所示將建立使用者組,例如 project
,可以本地訪問的 Subversion 儲存庫。
# chmod 2775 /srv/svn/project # chown -R root:src /srv/svn/project # chmod -R ug+rwX /srv/svn/project
屬於 project
組的本地使用者可以訪問在
"file:///localhost/srv/svn/project
" 或
file:///srv/svn/project
" 下
svn(1)
中的新 Subversion 儲存庫。你必須在 "umask 002
" 下執行諸如
svn
, svnserve
,
svnlook
和 svnadmin
命令,來確保使用者組可以訪問。
使用者組可以訪問的 Subversion 儲存庫的 URL 為
"example.com:/srv/svn/project
"。至於 SSH 訪問,你能夠在
svn(1)
中的 "svn+ssh://example.com:/srv/svn/project
" URL 訪問它。
對於 Subversion 來說,許多專案使用類似如下的目錄樹來彌補它的分支和標籤的不足。
----- module1 | |-- branches | |-- tags | | |-- release-1.0 | | `-- release-2.0 | | | `-- trunk | |-- file1 | |-- file2 | `-- file3 | `-- module2
![]() |
提示 |
---|---|
你必須使用 " |
按如下所示建立 "~/path/to/module1
" 路徑下的新的本地源目錄樹。
$ mkdir -p ~/path/to/module1; cd ~/path/to/module1
把檔案新增到 "~/path/to/module1
" 下的新的本地源目錄樹。
把它匯入到 Subversion 的時候帶有以下的引數。
模組名: "module1
"
Subversion 位置 URL: "file:///srv/svn/project
"
Subversion 目錄: "module1/trunk
"
Subversion 標籤: "module1/tags/Release-initial
"
$ cd ~/path/to/module1 $ svn import file:///srv/svn/project/module1/trunk -m "Start module1" $ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-initial
或者,如下所示。
$ svn import ~/path/to/module1 file:///srv/svn/project/module1/trunk -m "Start module1" $ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-initial
![]() |
提示 |
---|---|
你能夠用像 " |
這裡給出使用 Subversion 及其原生客戶端的典型工作流示例。
![]() |
提示 |
---|---|
|
檢視如下所示的 URL "file:///srv/svn/project
" 指向的 Subversion
專案上所有可用的模組。
$ svn list file:///srv/svn/project module1 module2 ...
按如下所示的檢出 "module1/trunk
" 到 "module1
"
目錄。
$ cd ~/path/to $ svn co file:///srv/svn/project/module1/trunk module1 $ cd module1
按需修改裡面的內容。
通過如下所示的命令來檢查改變,其作用相當於使用 "diff -u [repository] [local]
"。
$ svn diff
你發現自己改壞了 "file_to_undo
" 檔案,而其他的檔案都是好的。
按如下所示的用 Subversion 中的乾淨副本來覆蓋 "file_to_undo
" 檔案。
$ svn revert file_to_undo
按如下所示的把已經更新了的本地源目錄樹儲存到 Subversion。
$ svn ci -m "Describe change"
按如下所示的建立 "file_to_add
" 檔案並把它新增到 Subversion。
$ vi file_to_add $ svn add file_to_add $ svn ci -m "Added file_to_add"
按如下所示更新工作拷貝到 Subversion 中的最新版本。
$ svn up
當心以 "C filename
" 開頭的行,這意味著衝突的改變。
檢視檔案中未經修改的程式碼,例如 "filename.r6
",
"filename.r9
" 和 "filename.mine
" 檔案。
查詢檔案中的 "<<<<<<<
" 和
">>>>>>>
" 來獲得衝突的改變的資訊。
按需更改檔案來解決衝突。
按如下所示新增一個釋出標籤 "Release-1
"。
$ svn ci -m "last commit for Release-1" $ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-1
繼續編輯檔案。
按如下所示移除釋出分支 "Release-1
"。
$ svn rm file:///srv/svn/project/module1/tags/Release-1
按如下所示把改變簽入到 Subversion。
$ svn ci -m "real last commit for Release-1"
按如下所示在最新的 Subversion 主幹的基礎上重新添加發布分支 "Release-1
"。
$ svn cp file:///srv/svn/project/module1/trunk file:///srv/svn/project/module1/tags/Release-1
按如下所示在 "module1/tags/Release-initial
"
路徑指定的最初版本的基礎上再建立一個路徑為
"module1/branches/Release-initial-bugfixes
" 的分支,並把它簽出到
"~/path/to/old
" 目錄。
$ svn cp file:///srv/svn/project/module1/tags/Release-initial file:///srv/svn/project/module1/branches/Release-initial-bugfixes $ cd ~/path/to $ svn co file:///srv/svn/project/module1/branches/Release-initial-bugfixes old $ cd old
![]() |
提示 |
---|---|
使用 " |
在基於原始版本的 "Release-initial-bugfixes
" 分支的本地源目錄樹上工作。
獨自在 "Release-initial-bugfixes
" 分支上工作...直到有其他人加入到此分支。
按如下所示同步其他人在此分支上改動的檔案。
$ svn up
按需更改檔案來解決衝突。
按如下所示把改變簽入到 Subversion。
$ svn ci -m "checked into this branch"
按如下所示更新本地目錄樹為主幹的最新版本。
$ svn switch file:///srv/svn/project/module1/trunk
按如下所示通過合併 "Release-initial-bugfixes
" 分支的方式來更新本地目錄樹
(內容為主幹的最新版本)。
$ svn merge file:///srv/svn/project/module1/branches/Release-initial-bugfixes
用編輯器來解決衝突。
按如下所示把改變簽入到 Subversion。
$ svn ci -m "merged Release-initial-bugfixes"
按如下所示建立歸檔。
$ cd .. $ mv old old-module1-bugfixes $ tar -cvzf old-module1-bugfixes.tar.gz old-module1-bugfixes $ rm -rf old-module1-bugfixes
![]() |
提示 |
---|---|
你能夠用像 " |
![]() |
提示 |
---|---|
通過 " |