章 10. 資料管理

內容目錄

10.1. 共享,拷貝和存檔
10.1.1. 存檔和壓縮工具
10.1.2. 複製和同步工具
10.1.3. 歸檔語法
10.1.4. 複製語法
10.1.5. 查詢檔案的語法
10.1.6. 歸檔媒體
10.1.7. 可移動儲存裝置
10.1.8. 選擇用於分享資料的檔案系統
10.1.9. 網路上的資料分享
10.2. 備份和恢復
10.2.1. 備份和恢復策略
10.2.2. 實用備份套件
10.2.3. 備份技巧
10.2.3.1. GUI(圖形使用者介面)備份
10.2.3.2. 掛載事件觸發的備份
10.2.3.3. 時間事件觸發的備份
10.3. 資料安全基礎
10.3.1. GnuPG 金鑰管理
10.3.2. 在檔案上使用 GnuPG
10.3.3. 在 Mutt 中使用 GnuPG
10.3.4. 在 vim 中使用 GnuPG
10.3.5. MD5 校驗和
10.3.6. 密碼金鑰環
10.4. 原始碼合併工具
10.4.1. 從原始碼檔案匯出差異
10.4.2. 原始碼檔案移植更新
10.4.3. 互動式移植
10.5. Git
10.5.1. 調配 Git 客戶端
10.5.2. 基本的 Git 命令
10.5.3. Git 技巧
10.5.4. Git 參考
10.5.5. 其它的版本控制系統

以下是關於在 Debian 系統上管理二進位制和文字資料的工具及其相關提示。

[警告] 警告

為避免 競爭情況,不應當對正在進行寫操作的裝置和檔案,多個程序進行不協調的寫操作。採用flock(1) 的 檔案鎖定 機制可用於避免這種情況。

資料的安全和它的受控共享有如下幾個方面。

  • 存檔檔案的建立

  • 遠端儲存存取

  • 複製

  • 跟蹤修改歷史

  • 促進資料共享

  • 防止未經授權的檔案存取

  • 檢測未經授權的檔案修改

這些可以通過使用工具集來實現。

  • 存檔和壓縮工具

  • 複製和同步工具

  • 網路檔案系統

  • 移動儲存媒介

  • 安全 shell

  • 認證體系

  • 版本控制系統工具

  • 雜湊演算法和加密工具

以下是 Debian 系統上可用的存檔和壓縮工具的預覽。

表格 10.1. 存檔和壓縮工具列表

軟體包 流行度 大小 副檔名 指令 描述
tar V:902, I:999 3077 .tar tar(1) 標準的歸檔工具(預設)
cpio V:440, I:998 1199 .cpio cpio(1) Unix System V 風格的歸檔器,與 find(1) 一起使用
binutils V:172, I:629 144 .ar ar(1) 建立靜態庫的歸檔工具
fastjar V:1, I:13 183 .jar fastjar(1) Java 歸檔工具(類似 zip)
pax V:8, I:14 170 .pax pax(1) 新的 POSIX 歸檔工具,介於 tarcpio 之間
gzip V:876, I:999 252 .gz gzip(1), zcat(1), … GNU LZ77 壓縮工具(預設)
bzip2 V:166, I:970 112 .bz2 bzip2(1), bzcat(1), … Burrows-Wheeler block-sorting 壓縮工具有著比 gzip(1) 更高的壓縮率 (跟 gzip 有著相似的語法但速度比它慢)
lzma V:1, I:16 149 .lzma lzma(1) LZMA 壓縮工具有著比 gzip(1) 更高的壓縮率(不推薦)
xz-utils V:360, I:980 1203 .xz xz(1), xzdec(1), … XZ 壓縮工具有著比 bzip2(1) 更高的壓縮率(壓縮速度慢於 gzip 但是比 bzip2 快; LZMA 壓縮工具的替代品)
zstd V:193, I:481 2158 .zstd zstd(1), zstdcat(1), … Zstandard 快速無失真壓縮工具
p7zip V:20, I:463 8 .7z 7zr(1), p7zip(1) 有著更高壓縮率的 7-zip 檔案歸檔器(LZMA 壓縮)
p7zip-full V:110, I:480 12 .7z 7z(1), 7za(1) 有著更高壓縮率的 7-Zip 檔案歸檔器(LZMA 壓縮和其他)
lzop V:15, I:142 164 .lzo lzop(1) LZO 壓縮工具有著比 gzip(1) 更高的壓縮和解壓縮速度 (跟 gzip 有著相似的語法但壓縮率比它低)
zip V:48, I:380 616 .zip zip(1) InfoZip:DOS 歸檔器和壓縮工具
unzip V:105, I:771 379 .zip unzip(1) InfoZIP:DOS 解檔器和解壓縮工具

[警告] 警告

除非你知道將會發生什麼,否則不要設定 "$TAPE" 變數。它會改變 tar(1) 的行為。

  • gzipped tar(1) 歸檔器用於副檔名是 ".tgz" 或者 ".tar.gz" 的檔案。

  • xz-compressed tar(1) 歸檔器用於副檔名是 ".txz" 或者 ".tar.xz" 的檔案。

  • FOSS 工具,例如 tar(1),中的主流壓縮方法已經按如下所示的遷移: gzipbzip2xz

  • cp(1),scp(1) 和 tar(1) 工具可能並不適用於一些特殊的檔案。cpio(1) 工具的適用範圍是最廣的。

  • cpio(1) 是被設計為與 find(1) 和其它指令一起使用,適合於建立備份指令碼的場景,因此,指令碼的檔案選擇部分能夠被獨立測試。

  • Libreoffice 資料檔案的內部結構是 ".jar" 檔案,它也可以使用 unzip 工具來開啟。

  • 事實上跨平臺支援最好的存檔工具是 zip。按照“zip -rX”的方式呼叫可以獲得最大的相容性。如果最大檔案大小需要納入考慮範圍,請同時配合“-s”選項使用。

如下是用不同的工具複製整個 "./source" 目錄中的內容。

rsync(8):

# cd ./source; rsync -aHAXSv . /dest
# cd ./source; rsync -aHAXSv . [email protected]:/dest

你能夠選擇使用“源目錄上的反斜槓”語法。

# rsync -aHAXSv ./source/ /dest
# rsync -aHAXSv ./source/ [email protected]:/dest

或者,如下所示。

# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . /dest
# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . [email protected]:/dest

GNU cp(1) 和 openSSH scp(1):

# cd ./source; cp -a . /dest
# cd ./source; scp -pr . [email protected]:/dest

GNU tar(1):

# (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - )
# (cd ./source && tar cf - . ) | ssh [email protected] '(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) 可以用 "-u" 選項來忽略接受端上更新的檔案。

find(1) 被用作從歸檔中篩選檔案也被用作拷貝指令 (參見節 10.1.3, “歸檔語法”節 10.1.4, “複製語法”) 或者用於 xargs(1) (參見節 9.4.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

這些指令會執行如下動作。

  1. 查詢 "/path/to" 下的所有檔案

  2. 限定全域性查詢的檔案系統並且使用的是 ERE (參見節 1.6.2, “正規表達式”)

  3. 通過停止處理的方式來排除匹配 ".*\.cpio" 或 ".*~" 正規表達式的檔案

  4. 通過停止處理的方式來排除匹配 ".*/\.git" 正規表達式的目錄

  5. 通過停止處理的方式來排除比 99MB (1048576位元組單元) 更大的檔案

  6. 顯示檔名,滿足以上搜索條件並且比 "/path/to/timestamp" 新的檔案

請留心以上例子中的 "-prune -o" 排除檔案的習慣用法。

[注意] 注意

對於非 Debian 系的 Unix-like 系統,有些參數可能不被 find(1) 指令所支援。在這種情況下,應該考慮調整匹配方法並用 "-print" 替代 "-print0"。你可能同樣需要更改其他相關的指令。

為重要的資料存檔尋找 儲存裝置 時,你應該注意它們的侷限性。對於小型的個人資料備份,我使用品牌公司的 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 和 紙只能寫一次,它們從根本上阻止了因為重寫導致的資料意外丟失。這是優點!

[提示] 提示

如果你需要更快更頻繁的進行大資料備份,那麼通過高速網路連線的遠端主機上的硬碟來實現備份,可能是唯一可行的方法。

[提示] 提示

如果你在使用一個可重複寫入的介質作為你的備份介質,使用支援只讀快照的 btrfszfs 檔案系統,也許是一個好注意。

可移動儲存裝置可能是以下的任何一種。

它們可以通過以下的方式來進行連線。

像 GNOME 和 KDE 這樣的現代桌面環境能夠在 "/etc/fstab" 檔案中沒有匹配條目的時候,自動掛載這些可移動裝置。

  • udisks2 包提供了守護程序和相關的實用程式來掛載和解除安裝這些裝置。

  • D-bus 建立事件來觸發自動處理。

  • PolicyKit 提供了所需的特權。

[提示] 提示

umount(8) 在自動掛載裝置的時候可能會帶有 "uhelper=" 參數。

[提示] 提示

只有當這些可移動裝置沒有在 "/etc/fstab" 檔案中列出時,桌面環境下才會自動掛載。

現代桌面環境下的掛載點被選為 "/media/username/disk_label",它可以被如下所示的來定製。

  • FAT 格式的檔案系統使用 mlabel(1) 指令

  • ISO9660 檔案系統使用帶有 "-V" 選項的 genisoimage(1) 指令

  • ext2/ext3/ext4 檔案系統使用帶有 "-L" 選項的 tune2fs(1) 指令

[提示] 提示

掛載時可能需要提供編碼選項(參見 節 8.1.3, “檔名編碼”)。

[提示] 提示

在圖形介面選單上移除檔案系統,可能會移除它的動態裝置節點例如 "/dev/sdc"。如果你想要保留它的裝置節點,你應該在指令列提示字元上輸入 umount(8) 指令來解除安裝它。

當你通過可移動儲存裝置與其他系統分享資料的時候,你應該先把它格式化為被兩種作業系統都支援的通用的 檔案系統。下面是檔案系統的列表。


[提示] 提示

檢視節 9.9.1, “使用 dm-crypt/LUKS 加密移動磁碟”來獲得關於使用裝置級加密的跨平臺的資料共享的資訊。

FAT 檔案系統被絕大多數的現代作業系統支援,它對於通過可行動硬碟進行的資料交換是非常有用的。

當格式化像裝有 FAT 檔案系統的跨平臺資料共享的可移動裝置時,以下應該是保險的選擇。

當使用 FAT 或 ISO9660 檔案系統分享資料時,如下是需要注意的安全事項。

  • tar(1),或cpio(1)指令壓縮檔案,目地是為了保留檔名,符號連結,原始的檔案許可權和檔案所有者資訊。

  • split(1) 指令把壓縮檔案分解成若干小於 2GiB的小檔案,使其免受檔案大小限制。

  • 加密壓縮檔案保護其內容免受未經授權的存取。

[注意] 注意

因為 FAT 檔案系統的設計,最大的檔案大小為 (2^32 - 1) bytes = (4GiB -1 byte)。對於一些老舊的 32 位系統上的應用程式而言,最大的檔案大小甚至更小(2^31 -1) bytes = (2GiB -1 byte)。Debian 沒有遇到後者的問題。

[注意] 注意

微軟系統本身並不建議在超過 200MB 的分割槽或者驅動器上使用 FAT。他們的 " Overview of FAT, HPFS, and NTFS File Systems 這篇文章突出顯示了微軟系統的缺點,例如低效的磁碟空間利用。當然了,我們在 Linux 系統上還是應該使用 ext4 檔案系統。

[提示] 提示

有關檔案系統和存取檔案系統的更多資訊,請參考 "Filesystems HOWTO"。

我們都熟知計算機有時會出問題,或者由於人為的錯誤導致系統和資料損壞。備份和恢復操作是成功的系統管理中非常重要的一部分。可能有一天你的電腦就會出問題。

[提示] 提示

保持你的備份系統簡潔並且經常備份你的系統,有備份資料比你採用的備份方法的技術先進要重要的多。

有3個關鍵的因素決定實際的備份和恢復策略。

  1. 知道要備份和恢復什麼。

  2. 知道怎樣去備份和恢復。

    • 安全的資料儲存:保護其免於覆蓋和系統故障

    • 經常備份:有計劃的備份

    • 冗餘備份:資料映象

    • 傻瓜式操作:單個簡單指令備份

  3. 評估涉及的風險和成本。

    • 資料丟失的風險

      • 資料至少是應該在不同的磁碟分割槽上,最好是在不同的磁碟和機器上,來承受檔案系統發生的損壞。重要資料最好儲存在一個只讀檔案系統上。[4]

    • 資料非法訪問的風險

      • 敏感的身份資料,比如 "/etc/ssh/ssh_host_*_key", "~/.gnupg/*", "~/.ssh/*", "~/.local/share/keyrings/*", "/etc/passwd", "/etc/shadow", "popularity-contest.conf", "/etc/ppp/pap-secrets", and "/etc/exim4/passwd.client" 應當使用加密備份。[5] (參見 節 9.9, “資料加密提示”。)

      • 即使在信任的系統上,也不能夠硬編碼系統登入密碼或者加密密碼到任何腳本里面。(參見 節 10.3.6, “密碼金鑰環”。)

    • 資料丟失的方式及其可能性

      • 硬體(特別是硬碟)將會損壞

      • 檔案系統可能會損壞,裡面的資料可能被丟失

      • 對違規安全訪問而言,遠端儲存系統不能夠被信任

      • 弱的密碼保護能夠被輕鬆的破解

      • 檔案許可權系統可以被破解

    • 備份所需的資源:人力,硬體,軟體,…

      • 使用 cron 任務或者 systemd 計時器任務來自動化排程備份工作

[提示] 提示

你能夠用 "debconf-set-selections debconf-selections" 命令恢復 debconf 調配資料,可以用 "dpkg --set-selection <dpkg-selections.list" 指令恢復 dpkg 篩選資料。

[注意] 注意

除非你知道自己做的是什麼,否則不要備份 /proc, /sys, /tmp, 和 /run 目錄下的偽檔案系統(參見 節 1.2.12, “procfs 和 sysfs”節 1.2.13, “tmpfs”)。它們是龐大且無用的資料。

[注意] 注意

當備份資料的時候,你可能希望停止一些應用程式的背景程式例如 MTA(參見節 6.2.4, “郵件傳輸代理 (MTA)”)。

以下是 Debian 系統上值得注意的實用備份程式套件的列表。

表格 10.5. 實用備份程式套件列表

軟體包 流行度 大小 說明
bacula-common V:8, I:10 2305 Bacula: 網路資料備份,恢復和核查-常見的支援檔案
bacula-client V:0, I:2 178 Bacula: 網路資料備份,恢復和核查-客戶端元軟體包
bacula-console V:0, I:3 112 Bacula: 網路資料備份,恢復和核查-文字終端
bacula-server I:0 178 Bacula: 網路資料備份,恢復和核查-伺服器端元軟體包
amanda-common V:0, I:2 9897 Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(庫)
amanda-client V:0, I:2 1092 Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(客戶端)
amanda-server V:0, I:0 1077 Amanda: 馬里蘭大學開發的高階自動化網路磁碟歸檔器(伺服器端)
backuppc V:2, I:2 3178 BackupPC 是用於備份 PC 機資料(基於磁碟)的高效能的企業級工具
duplicity V:30, I:50 1973 (遠端) 增量備份
deja-dup V:28, I:44 4992 duplicity 的 GUI(圖形使用者介面)前端
borgbackup V:11, I:20 3301 (遠端) 去重備份
borgmatic V:2, I:3 509 borgbackup 備份軟體的輔助軟體
rdiff-backup V:4, I:10 1203 (遠端) 增量備份
restic V:2, I:6 21385 (遠端) 增量備份
backupninja V:2, I:3 360 輕量,可擴展的 meta-backup 系統
flexbackup V:0, I:0 243 (遠端) 增量備份
slbackup V:0, I:0 151 (遠端) 增量備份
backup-manager V:0, I:1 566 指令列備份工具
backup2l V:0, I:0 115 用於可掛載媒介 (基於磁碟的) 的低維護的備份/恢復工具

備份工具有各自的專用的用途。

  • Mondo Rescue 是一個備份系統,它能夠方便的從備份 CD/DVD 等裝置中快速恢復整個系統,而不需要經過常規的系統安裝過程。

  • BaculaAmandaBackupPC 是全功能的備份實用套件,主要用於聯網的定期備份。

  • DuplicityBorg 是簡單的備份工具用於典型的工作站。

對於一個個人工作站,為伺服器環境設計的全功能備份套件工具也行不是最合適的。與此同時,已有的用於工作站的備份工具有一些不足。

這裡有一些技巧讓備份更加容易,只需使用者做最小的工作。這些技巧可以同任意備份工具一起使用。

出於演示的目的,讓我們假設基本使用者和組名為 penguin,建立一個備份和快照指令碼例子"/usr/local/bin/bkss.sh":

#!/bin/sh -e
SRC="$1" # source data path
DSTFS="$2" # backup destination filesystem path
DSTSV="$3" # backup destination subvolume name
DSTSS="${DSTFS}/${DSTSV}-snapshot" # snapshot destination path
if [ "$(stat -f -c %T "$DSTFS")" != "btrfs" ]; then
  echo "E: $DESTFS needs to be formatted to btrfs" >&2 ; exit 1
fi
MSGID=$(notify-send -p "bkup.sh $DSTSV" "in progress ...")
if [ ! -d "$DSTFS/$DSTSV" ]; then
  btrfs subvolume create "$DSTFS/$DSTSV"
  mkdir -p "$DSTSS"
fi
rsync -aHxS --delete --mkpath "${SRC}/" "${DSTFS}/${DSTSV}"
btrfs subvolume snapshot -r "${DSTFS}/${DSTSV}" ${DSTSS}/$(date -u --iso=min)
notify-send -r "$MSGID" "bkup.sh $DSTSV" "finished!"

這裡,只使用基本工具 rsync(1)來幫助備份,儲存空間使用 Btrfs 來高效利用。

[提示] 提示

提示:這個作者在他的工作站上使用他自己的類似 shell 指令碼"bss: Btrfs Subvolume Snapshot Utility"。

這裡是一個建立單擊 GUI(圖形使用者介面)圖示備份的例子。

對於每一次圖示單擊,你的資料從"~/Documents"備份到 USB 儲存裝置,並建立了一個只讀快照。

這裡是一個由掛載事件觸發的自動備份例子。

  • 節 10.2.3.1, “GUI(圖形使用者介面)備份” 的方式準備一個 USB 儲存裝置用於備份。

  • 建立一個如下的 systemd 服務單元檔案"~/.config/systemd/user/back-BKUP.service":

    [Unit]
    Description=USB Disk backup
    Requires=media-%u-BKUP.mount
    After=media-%u-BKUP.mount
    
    [Service]
    ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
    StandardOutput=append:%h/.cache/systemd-snap.log
    StandardError=append:%h/.cache/systemd-snap.log
    
    [Install]
    WantedBy=media-%u-BKUP.mount
    
  • 用下面的方式啟用這個 systemd 單元配置:

     $ systemctl --user enable bkup-BKUP.service
    

對於每一次掛載事件,你的資料從"~/Documents"備份到 USB 儲存裝置,並建立了一個只讀快照。

這裡,當前 systemd 在記憶體中的 systemd 掛載單元的名字,使用者使用 "systemctl --user list-units --type=mount" 來呼叫服務管理器來查詢。

這裡是一個由時間事件觸發的自動備份例子。

  • 節 10.2.3.1, “GUI(圖形使用者介面)備份” 的方式準備一個 USB 儲存裝置用於備份。

  • 建立一個如下的 systemd 時間單元檔案"~/.config/systemd/user/snap-Documents.timer":

    [Unit]
    Description=Run btrfs subvolume snapshot on timer
    Documentation=man:btrfs(1)
    
    [Timer]
    OnStartupSec=30
    OnUnitInactiveSec=900
    
    [Install]
    WantedBy=timers.target
    
  • 建立一個如下的 systemd 服務單元檔案"~/.config/systemd/user/snap-Documents.service":

    [Unit]
    Description=Run btrfs subvolume snapshot
    Documentation=man:btrfs(1)
    
    [Service]
    Type=oneshot
    Nice=15
    ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
    IOSchedulingClass=idle
    CPUSchedulingPolicy=idle
    StandardOutput=append:%h/.cache/systemd-snap.log
    StandardError=append:%h/.cache/systemd-snap.log
    
  • 用下面的方式啟用這個 systemd 單元配置:

     $ systemctl --user enable snap-Documents.timer
    

對於每一次時間事件,你的資料從"~/Documents"備份到 USB 儲存裝置,並建立了一個只讀快照。

這裡,當前 systemd 在記憶體中的 systemd 使用者時間單元的名字,使用 "systemctl --user list-units --type=timer" 來呼叫服務管理器來查詢。

對於現在的桌面系統,這個 systemd 方案,比起傳統的 Unix at(1)、cron(8) 或 anacron 方式,能夠提供更精緻的細粒度控制。

資料安全基礎設施是資料加密,訊息摘要和簽名工具的結合。


參見 節 9.9, “資料加密提示”dm-cryptfscrypt,它們透過 Linux 核心模組實現了自動資料加密架構。

如下是 GNU 隱私衛士 基本的金鑰管理命令。


信任碼含義.


如下指令上傳我的 "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" 選項.

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. 原始碼合併工具列表

軟體包 流行度 大小 指令 說明
patch V:97, I:700 248 patch(1) 給原檔案打補丁
vim V:95, I:369 3743 vimdiff(1) 在 vim 中並排比較兩個檔案
imediff V:0, I:0 200 imediff(1) 全屏互動式兩路/三路合併工具
meld V:7, I:30 3536 meld(1) 比較和移植檔案(GTK)
wiggle V:0, I:0 175 wiggle(1) 應用被拒絕的補丁
diffutils V:862, I:996 1735 diff(1) 逐行比較兩個檔案
diffutils V:862, I:996 1735 diff3(1) 逐行比較和合並三個檔案
quilt V:2, I:22 871 quilt(1) 管理系列補丁
wdiff V:7, I:51 648 wdiff(1) 在文字檔案中,顯示單詞的不同
diffstat V:13, I:121 74 diffstat(1) 通過 diff 生成一個改變柱狀圖
patchutils V:16, I:119 232 combinediff(1) 從兩個增量補丁建立一個積累補丁
patchutils V:16, I:119 232 dehtmldiff(1) 從一個 HTML 頁面提取出一個 diff
patchutils V:16, I:119 232 filterdiff(1) 從一個 diff 檔案裡面提取或者排除 diff 檔案
patchutils V:16, I:119 232 fixcvsdiff(1) 修復由 CVS patch(1) 錯誤建立的 diff 檔案
patchutils V:16, I:119 232 flipdiff(1) 交換兩個補丁的順序
patchutils V:16, I:119 232 grepdiff(1) 顯示哪些檔案是由匹配正規表達式的補丁修改
patchutils V:16, I:119 232 interdiff(1) 顯示在兩個統一格式 diff 檔案(基於同一個檔案的兩個不同 diff 檔案)之間的差異
patchutils V:16, I:119 232 lsdiff(1) 顯示哪些檔案由補丁修改
patchutils V:16, I:119 232 recountdiff(1) 重新計算通用內容 diff 檔案的數量和偏移
patchutils V:16, I:119 232 rediff(1) 修復手工編輯 diff 檔案的數量和偏移
patchutils V:16, I:119 232 splitdiff(1) 隔離出增量補丁
patchutils V:16, I:119 232 unwrapdiff(1) 識別已經被分詞的補丁
dirdiff V:0, I:1 167 dirdiff(1) 顯示目錄樹之間的不同並移植改變
docdiff V:0, I:0 553 docdiff(1) 逐詞逐字的比較兩個檔案
makepatch V:0, I:0 100 makepatch(1) 生成擴展補丁檔
makepatch V:0, I:0 100 applypatch(1) 套用擴展補丁檔

Git 是這些天選擇的用於 版本控制系統 version control system (VCS) 的工具,因為 Git 能夠同時在本地和遠端原始碼管理上,做任何事情。

通過 Debian Salsa service,Debian 能夠提供免費的 Git 服務。在 http://wiki.debian.org/Salsa 能找到它的說明文件。

下面是一些 Git 相關軟體包。


你可以在 "~/.gitconfig" 裏面設置幾個 Git 接下來需要使用的全局調配,比如說你的名字和電子郵件地址。

$ git config --global user.name "Name Surname"
$ git config --global user.email [email protected]

你也可以按如下所示定製 Git 的預設行為。

$ git config --global init.defaultBranch main
$ git config --global pull.rebase true
$ git config --global push.default current

如果你習慣使用 CVS 或 Subversion 指令,你也許希望設置如下幾個指令別名。

$ git config --global alias.ci "commit -a"
$ git config --global alias.co checkout

你能夠通過如下方式檢查你的整體組態。

$ git config --global --list

Git 操作涉及幾個資料。

  • 工作樹目錄保持面向使用者的檔案,你可以對這些檔案做修改。

    • 需要被記錄的改變,必須明確的被選擇並暫存到索引。這是 git addgit rm 命令。

  • 索引保持暫存檔案。

    • 在接下來的請求之前,暫存檔案將被提交到本地倉庫。這個是 git commit 命令。

  • 本地倉庫保持已經提交的的檔案。

    • Git 記錄提交資料的連結歷史並在倉庫裡面將它們作為分支組織。

    • 本地倉庫透過 git push 命令傳送資料到遠端倉庫。

    • 本地倉庫能夠透過 git fetchgit pull 命令從遠端倉庫接收資料。

      • git pull 命令在 git fetch 後執行 git mergegit rebase 命令。

      • 這裡,git merge 聯合兩個獨立分支的歷史結尾到一個點。(在沒有定製的 git pull ,這個是預設的,同時對上游作者釋出分支到許多人時,也是好的 )

      • 這裡,git rebase 建立一個遠端分支的序列歷史的單個分支,跟著本地分支。(這是定製 pull.rebase true 的情況,對我們其餘的用途有用。)

  • 遠端倉庫保持已經提交的檔案。

    • 到遠端倉庫的通訊,使用安全的通訊協議,比如 SSH 或 HTTPS。

工作樹是在 .git/ 目錄之外的檔案。在 .git/ 目錄裡面的檔案,包括索引、本地倉庫資料和一些 git 配置的文字檔案。

這裡是主要的 Git 命令概覽。


下面是一些 Git 技巧。

表格 10.13. Git 技巧

Git 命令列 功能
gitk --all 參看完整的 Git 歷史和操作,比如重置 HEAD 到另外一個提交、挑選補丁、建立標籤和分支……
git stash 得到一個乾淨的工作樹,不會丟失資料
git remote -v 檢查遠端設定
git branch -vv 檢查分支設定
git status 顯示工作樹狀態
git config -l 列出 git 設定
git reset --hard HEAD; git clean -x -d -f 反轉所有工作樹的改變並完全清理它們
git rm --cached filename 反轉由 git add filename 改變的暫存索引
git reflog 獲取參考日誌(對從刪除的分支中恢復提交有用)
git branch new_branch_name HEAD@{6} 從 reflog 資訊建立一個新的分支
git remote add new_remote URL 增加一個由 URL 指向的遠端倉庫 new_remote
git remote rename origin upstream 遠端倉庫的名字從 origin 重新命名到 upstream
git branch -u upstream/branch_name 設定遠端跟蹤到遠端倉庫 upstream 和它的分支名 branch_name
git remote set-url origin https://foo/bar.git 改變 origin 的 URL
git remote set-url --push upstream DISABLED 禁止推送到 upstream(編輯 .git/config 來重新啟用)
git remote update upstream 獲取 upstream 倉庫中所有遠端分支更新
git fetch upstream foo:upstream-foo 建立本地(可能是孤立的)upstream-foo 分支,作為upstream 倉庫中 foo 分支的一個複製
git checkout -b topic_branch ; git push -u topic_branch origin 製作一個新的 topic_branch 並把它推送到 origin
git branch -m oldname newname 本地分支改名
git push -d origin branch_to_be_removed 刪除遠端分支(新的方式)
git push origin :branch_to_be_removed 刪除遠端分支(老的方式)
git checkout --orphan unconnected 建立一個新的 unconnected 分支
git rebase -i origin/main origin/main 重新排序、刪除、壓縮提交到一個乾淨的分支歷史
git reset HEAD^; git commit --amend 壓縮最後兩個提交為一個
git checkout topic_branch ; git merge --squash topic_branch 壓縮整個 topic_branch 到一個提交
git fetch --unshallow --update-head-ok origin '+refs/heads/*:refs/heads/*' 反轉一個淺克隆到一個所有分支的完整克隆
git ime 分開最後的提交到一系列單個逐一檔案的小提交。(要求 imediff
git repack -a -d; git prune 本地倉庫重新打包到一個單獨的包中(這可能限制從刪除分支裡面恢復丟失資料等機會)

[警告] 警告

不要使用帶空格的標簽字串。即使一些工具,如 gitk(1) 允許你使用它,但會阻礙其它 git 指令。

[注意] 注意

如果一個本地分支推送到一個已經變基或者壓縮過的倉庫,推送這樣的分支有風險,並要求 --force 選項。這通常對 main 分支來說不可接受,但對於一個移植到 main 分支前的特定分支,是可以接受的。

[注意] 注意

從指令列通過 "git-xyz" 直接呼叫 git 子指令的方式,從 2006 年早期開始就被取消。

[提示] 提示

如果有一個可執行檔案 git-foo 在路徑環境變數 $PATH 裡面,在命令列輸入沒有中劃線的 "git foo",則將呼叫 git-foo.這是 git 命令的一個特性。

看下面。



[4] 一個只能寫一次的媒介,例如 CD/DVD-R, 能防止覆蓋事故。(參見 節 9.8, “二進位制資料” 怎樣在 shell 命令列寫入儲存媒介。GNOME 桌面圖形環境可以讓你輕鬆的透過選單:“位置 → CD/DVD 燒錄”來實現寫入操作。)

[5] 這些資料中的一些,不能夠透過在系統裡面輸入同樣的字串來重新生成。

[6] 如果你使用 "~/.vimrc" 代替 "~/.vim/vimrc",請進行相應的取代。