如何在Ubuntu 16.04與18.04上使用at指令進行一次性排程

前言

最近有一台主機上面的服務的階段性任務已經達成了,而上面的主機相關的檔案需要進行封存,而剛好備份有時間上的要求,需求如下:

  • 需要在6/29的17:00之後備份整個根目錄系統與資料庫備份
  • 需要在7/4的17:00之後進行備份整個根目錄系統與資料庫備份

從上述的指定時間來看,明顯是有一個指定的時間需要做指定的事情。

而主要每個排程有兩個備份的工作:

  • 主機上面的資料庫備份
  • 主機上面的根目錄檔案系統備份
  • 此主機為使用MySQL資料庫

想到這邊,可能一開始靈光一現,會想到使用Cron服務與crontab指令來解決,但是不然,原因是因為Cron排程是一個循環工作,一個固定時間週而復始的執行,那上述的需求就不適合了。

本文章中,將會介紹與利用at指令進行上述的方式達成上述的單一指定時間的排程工作。

前置條件

  • 一台主機Ubuntu 16.04或是Ubuntu 18.04
  • 已經安裝好at的套件,若沒有,也沒關係,後面會提到
  • 確切的使用者已經可以使用sudo來暫時取得root使用者的權限

安裝at套件

要開始使用at套件之前,需要先將此套件給安裝好,安裝方式如下:


sudo apt-get update

sudo apt-get install at

成功安裝好at套件之後,則可以使用下列的指令進行檢查目前at服務的運行狀況:


# 檢查目前at服務狀態

sudo systemctl status atd.service

# 檢查目前at服務是否已經啟用

sudo systemctl is-enabled atd.service

# enabled

接著,可以利用下面的指令來測試一下 at 指令該如何使用,使用方式有下列幾種:


logger "Hello from at" | at now + 10 minute

上述意思是,在現在時間後的10分鐘會將前面的 Hello from at文字訊息寫到/var/log/syslog的檔案裡面。


logger "Hello from at" | at "17:00"

上述意思是,在今天的下午17:00會將前面的 Hello from at文字訊息寫到/var/log/syslog的檔案裡面。


logger "Hello from at" | at "17:00 June 30"

上述意思是,在今年的6/30的下午17:00會將前面的 Hello from at文字訊息寫到/var/log/syslog的檔案裡面。


logger "Hello from at" | at "17:00 June 30 2020"

上述意思是,在2020年的6/30的下午17:00會將前面的 Hello from at文字訊息寫到/var/log/syslog的檔案裡面。

還有很多種方法,不過基本上上述的指令就已經很夠用了。

接著,還需要有備份的指令,因此我們先產生出下列的備份資料庫指令:


#!/bin/bash

MYSQL_USER="user"

MYSQL_PASSWORD="password"

BACKUP_DIR="/backup/directory"

db="database_name"

backupName="backup_database_archive_file_name"

/usr/bin/mysqldump --lock-tables=false --single-transaction --quick --force --opt --user=$MYSQL_USER -p$MYSQL_PASSWORD --databases $db | gzip > $BACKUP_DIR"/"$backupName

  • MYSQL_USER為MySQL資料庫的使用者
  • MYSQL_PASSWORD為MySQL資料庫的使用者密碼
  • BACKUP_DIR為將備份檔案儲存的目標目錄 (destination folder)
  • db為MySQL資料庫名稱
  • backupName為備份資料庫檔案名稱

接著,產生出備份全系統的指令:


cd /

tar -cvpzf /mnt/user/backup_root_fs.tar.gz --one-file-system /

上述指令指的是:

  • 切換到根目錄底下(/)
  • 利用tar指令壓縮(-c)
  • 並印出訊息(-v)
  • 保留檔案與目錄相關權限(-p)
  • 以gzip方式進行壓縮(-z)
  • 將檔案壓縮並輸出指定的壓縮檔案(含指定路徑) (-f)
  • 上述所有選項合在一起為:-cvpzf
  • –one-file-system只備份根目錄本地檔案系統並會忽略外部掛載進來的檔案系統與目錄,舉例來說:
    • /mnt/cdrom
    • /mnt/nfs
    • /iscsi
    • /boot
    • 上述這些檔案系統都會在tar備份時候進行忽略

接著將上述的檔案合寫成一個shell script,並取名叫做backup.sh,其檔案內容如下:


#!/bin/bash

MYSQL_USER="user"

MYSQL_PASSWORD="password"

BACKUP_DIR="/backup/directory"

db="database_name"

backupName="backup_database_archive_file_name"

/usr/bin/mysqldump --lock-tables=false --single-transaction --quick --force --opt --user=$MYSQL_USER -p$MYSQL_PASSWORD --databases $db | gzip > $BACKUP_DIR"/"$backupName

cd /

tar -cvpzf /mnt/user/backup_root_fs.tar.gz --one-file-system /

接著再搭配at指令就會變成:


at "18:30 June 29 2020" -f ./backup.sh

at "18:30 July 4 2020" -f ./backup.sh

接著可以使用 atq 或是 at -l 指令看到如下的排程工作清單:


10 Tue Jun 30 18:30:00 2020 a user
9 Sat July 04 18:20:00 2020 a user

上述的排程工作描述為:

  • 第一個字串為排程工作的編號
  • 第二個字串為星期幾
  • 第三個字串幾月月份名稱
  • 第四個字串為幾號
  • 第五個字串為工作排程的時間
  • 第六個字串為年份
  • 第七個與第八個字串為使用者名稱user

這樣就完成了使用at指令設定排程了。

若要刪除某個at清單中的工作排程,則可以使用atrm這個指令刪除,使用方式如下:


atrm 11

上述指令的意思是,工作編號為11的排程進行刪除。

參考資料

  • https://help.ubuntu.com/community/BackupYourSystem/TAR
  • https://linuxize.com/post/at-command-in-linux/
  • https://linuxconfig.org/how-to-schedule-tasks-using-at-command-on-linux
  • https://gist.github.com/peter279k/0a99b260b983d8e78b71fab378049fad