2020/07/09

插入隨身碟即自動備份的方法

Auto Backup Files After Inserting A Storage Device


【摘要】
敘述將指定的隨身碟連接到電腦後,即自動備份檔案到隨身碟的方法。


【目錄】

    【前言
    【方法
      【規則檔
      【序號
      【程式檔
    【後語

【前言】


定期備份檔案是非常重要的事。如果是誤刪檔案,還有機會用復原軟體救回來。但硬碟若突然故障,會令人欲哭無淚的。


個人每天都會將重要檔案備份到隨身碟,每週則將整個系統備份到外接硬碟。偶而遇到檔案發生問題時,都會非常慶幸有按時備份。


本文敘述將特定的隨身碟插入 USB 插座後,會自動備份的方法。作業系統是自己組合的 Debian GNU/Linux 10。


【方法】


原理是:插入隨身碟時,系統會偵測到,並執行一些動作。就利用這種現象,添加一些設定,讓系統備份檔案。這些設定放在一個稱為規則檔的裡面,而此檔是在 /etc/udev/rules.d/ 目錄中。這些設定要指定一個指令檔,當系統偵測到特定的隨身碟時,執行這個指令檔。依本文的主題來看,指令檔的內容當然是備份檔案,不過也可以做其他的事。


【規則檔】


  一、以 root 權限在 /etc/udev/rules.d/ 目錄新增 autobackup.rules 檔,內容為:

  1. ACTION=="add", ATTRS{serial}=="2318460089", RUN+="/home/USER/.local/bin/rsync_autobackup"
  1. ACTION: 動作
  2. ==: regular expression 比對
  3. add: 新增裝置
  4. ATTRS: 屬性;S 是必需的,不能用 ATTR
  5. serial: 序號
  6. 2318460089: 本例隨身碟的產品序號;用序號較具獨特性,下文會敘述取得的方法
  7. RUN: 符合前面的比對條件即執行指定的指令
  8. +=: 增加
  9. /home/USER/.local/bin/rsync_autobackup: 欲執行的指令檔

  這些設定的意思是:當有插入(add)序號(serial)為 2318460089 裝置的動作(ACTION)時,就執行(RUNrsync_autobackup 檔。


  以上的設定要連成一行,若分行,行末要加反斜線 \。


  二、通常在 /etc/udev/rules.d/ 和 /lib/udev/rules.d/ 目錄裡的規則檔都有編號,以決定處理的順序。但經測試發現自己加的 autobackup.rules 檔不論編號為何都一樣,不加也可以,所以本例沒有加,這會排在最後面處理。


  三、RUN 的指令:

  • 必需用完整路徑
  • 可以有引數
  • 若有空格,可用單引號
  • 若是檔案,可以放在自己家裡

  四、RUN 的指令若是執行一指令檔:

  • 記得將之改為可執行檔
  • 其內的指令也必需用全路徑
  • 不能用 $HOME 等環境變數
  • 不能有互動型指令,例如顯示對話框詢問使用者等
  • 執行時間不可太長,三分鐘即會被系統中斷

  五、新增規則檔後,用以下指令載入:

  1. sudo udevadm control --reload

  六、測試規則用:

  1. udevadm test /class/block/sdb2

  最後一項是裝置在 /sys/ 中的路徑。


【序號】


  一、假設插入的隨身碟是 sdb,可用以下指令找到序號:

  1. udevadm info --attribute-walk /dev/sdb

  --attribute-walk 選項會逐一列出上層目錄的資訊,而且可以直接看到要設定的屬性。


  二、rules 檔篩選裝置時,需要的是獨特的屬性,只要能篩選出該裝置,一項即可。譬如產品序號,只要序號夠長,通常不會重複,所以找 ATTRS{serial}。網路有不少文章說 rules 要用:KERNEL(S)、SUBSYSTEM(S)、SYMLINK 等,事實上都不需要。至於製造商或其代號,或產品編號、型號之類的有:

  • ATTRS{idProduct}
  • ATTRS{idVendor}
  • ATTRS{manufacturer}
  • ATTRS{model}
  • ATTRS{vendor}

  這些重複的機率較大,譬如同一廠牌的隨身碟有兩個時。


  三、要快速找出序號可用:

  1. udevadm info --attribute-walk /dev/sdb | grep "{serial}"

  但這至少會有兩個結果,一個是隨身碟的序號,一個是提供 USB 插座的界面卡的序號;通常第一個是隨身碟的,因為這個指令是「逐層地」列出相關資訊。


【程式檔】


#!/usr/bin/sh
#用 udev rules 執行此檔時,上一行是必需的(當然也可以用其他的 shell)
#用 udev rules 執行的指令必需用全路徑
 
#目標分割區的 UUID
Uuid=d44cb883-6d29-4536-a409-d53b55c6c0c4
#此為本例隨身碟之第二分割區;若更改 UUID,記得更新
#用 UUID 不會搞錯;若用 /dev/sdxn,可能會錯,因為可能是 sdb,也可能是其他的
 
#掛載目錄
MountPoint=/media/USER/Backup
 
#掛載隨身碟
/usr/bin/sudo /usr/bin/mount --uuid ${Uuid} ${MountPoint}
 
#儲存輸出碼
Mount=$?
 
/usr/bin/sleep 2
#掛載需要時間
 
#檢查
if [ ${Mount} -ne 0 ]; then exit; fi
#若未掛載成功即中止
 
#把 HOME 備份到隨身碟
/usr/bin/rsync --archive --delete --delete-excluded --itemize-changes --modify-window=3 --progress --protect-args --exclude='.thumbnails/' --exclude='.cache/' --exclude='no_backup/' --exclude='VirtualBox VMs/' /home/USER ${MountPoint}
 
#用 udev rules 執行此檔,最後不需卸載,其掛載是內部的,在 /proc/mounts 沒有記錄
#若直接執行此檔,需自行卸載
#/usr/bin/sudo /usr/bin/umount ${MountPoint}

【後語】


一、如果掛載有問題,試試:

  1. sudo systemctl daemon-reload
  2. sudo systemctl restart systemd-udevd.service

二、如果執行有問題,看看:

  1. sudo tail /var/log/syslog

三、建議隨身碟用有閃燈的,這樣才知道是否有在備份,以及是否備份結束了。或是螢幕上方或下方的工作列能顯示 CPU 狀態也可以。


四、請參閱 man udevman udevadm


沒有留言:

張貼留言