樹莓派:最好的安排

Vamei發表於2017-01-12

作者:Vamei 出處:http://www.cnblogs.com/vamei 嚴禁轉載。

 

樹莓派是一款低成本的電腦,因此它的一個應用場景就是充當小型的伺服器。我平時就會在自己的區域網下接入一個樹莓派,做一些資料備份和上傳的工作。這種時候,我們希望減少對樹莓派的直接操作,就可以採用一些任務規劃的手段,來讓樹莓派自動執行任務。

shutdown

reboot

sleep 10 

 

用cron規劃任務

cron是UNIX系統下常用的任務規劃軟體。你可以在cron中要求系統在特定的時間執行特定的任務。cron在系統中有一個執行著的守護程式。當系統時間符合某一條規劃記錄時,守護程式就會啟動相應的任務。在樹莓派應用行中執行下面命令,就可以找到cron的守護程式:

ps aux | grep cron

 

結果如下:

root       424  0.0  0.2   5072  2384 ?        Ss   14:40   0:00 /usr/sbin/cron -f
pi        6938  0.0  0.2   4280  2008 pts/1    S+   17:42   0:00 grep --color=auto cron

記錄中的第一條,就是cron的程式。

 

如果想要規劃任務,那麼可以用下面的命令來編輯規劃記錄:

crontab -e

在規劃記錄中,每一行為一條記錄,#開始的是註釋。每一行記錄又分為6列,用空格分隔,分別表示分鐘(m,0-59)、小時(h,0-23)、一個月中的哪一天(dom,1-31)、月(mon,1-12)、一個星期中的哪一天(dow,0-6)、以及要執行的命令。在填寫規劃時間的時候,除了用數字,還可以用*,用來表示所有:

 

# m h  dom mon dow   command
 30 5   10   3   *   touch /tmp/test.log

上面表示每年3月10號5點30分,執行touch /tmp/test.log。

 

# m h  dom mon dow   command
 10 18   *   *   *   echo "Hello World" > /home/pi/log

每天的18點10分執行echo "Hello World" > /home/pi/log。

 

一列中,還可以規劃多個時間點,例如:

# m h  dom mon dow   command
 10 2-4  *   *   *   echo "Hello World" > /home/pi/log

每天2:10、3:10和4:10執行。也就是說,“N-M”表示了從N到M的範圍。

 

# m h  dom mon dow   command
 30 1,5  *   *   *   echo "Hello World" > /home/pi/log

每天1:30和5:30執行。也就是說,“N,M”表示了N和M兩個時間點。

 

規劃記錄crontab儲存後,cron就將按照規劃,在對應的時間執行對應的命令。每個使用者有一個自己的crontab,當cron要執行規劃時,也會以相應的使用者身份來執行。我是以pi使用者修改儲存的crontab,cron就會以pi的身份來執行各個命令。如果想修改其他使用者的crontab,那麼可以用-u關鍵字:

sudo crontab -e -u root

 

用cron來開機啟動 

cron除了做時間規劃,還可以用於開機啟動。在crontab中新增下面一行記錄,就可以方便的實現:

@reboot touch /home/pi/reboot.log

 

用/etc/init.d實現開機啟動

在樹莓派下的/etc/init.d資料夾下有很多指令碼,比如我們已經瞭解了的cron。這個cron指令碼把cron這個守護程式包裝成了一個服務,定義了它在啟動、重啟和終止時的具體行為。這樣,使用者在啟用相應的服務時,就不需要進行太複雜的設定。當服務終止時,作業系統也能根據指令碼的定義,自動地回收相關資源。使用者還能把重要的服務設定成開機啟動,省了手動開啟的麻煩。因此,我們在/etc/init.d中內看到很多默默工作的服務,如ssh、bluetooth、rsync等。

 

服務指令碼遵循特定的格式。如下面的/etc/init.d/test指令碼:

#!/bin/sh
# Start/stop the test daemon.
#
### BEGIN INIT INFO
# Provides:          test
# Required-Start:    $remote_fs $syslog $time
# Required-Stop:     $remote_fs $syslog $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: test
# Description:       test
### END INIT INFO

do_start() {
    echo "start"
}

do_stop() {
    echo "stop"
}

do_restart() {
    echo "restart"
}

do_status() {
    echo "status"
}

do_fallback() {
    echo "fallback"
}

case "$1" in
start)  do_start
        ;;
stop)   do_stop
        ;;
restart) do_restart
        ;;
status) do_status
        ;;
*)      do_fallback
        ;;
esac
exit 0

 

指令碼的一開始有頭部資訊。頭部資訊中除了基本的介紹,還有其他資訊。Required-Start說明了該test應用啟動前,系統必須啟動的其他應用。Required-Stop列出的應用必須在test應用結束後結束。Default-Start和Default-Stop中說明的預設執行級別。Unix系統可以在不同執行模式下工作,如單使用者模式、多使用者模式,每種模式就稱為一個執行級別。大多數UNIX系統遵照: 

執行級別:
0 停機,關機
1 單使用者,無網路連線,不執行守護程式,不允許非超級使用者登入
2 多使用者,無網路連線,不執行守護程式
3 多使用者,正常啟動系統
4 使用者自定義
5 多使用者,帶圖形介面
6 重啟

test指令碼中,預設支援的執行級別是2、3、4、5。

 

在指令碼的主體程式中包含了一個case分支結構,說明了應用在進入啟動(start)、停止(stop)、重啟(restart)、狀態查詢(status)狀態時應該採用的動作。我們可以用service命令來手動讓指令碼切換狀態:

sudo service test start

指令碼中相應的動作會被呼叫。

 

/etc/init.d/myscript還不能隨機啟動。Linux在開機啟動時,真正檢查的是/etc/rcN.d資料夾,執行其中的指令碼。這裡的N代表了執行級別。比如說在執行級別2時,Linux會檢查/etc/rc2.d資料夾,執行其中的指令碼。我們需要把/etc/init.d中的服務複製到或者建立軟連線到/etc/rcN.d,才能服務在該執行級別的開機啟動。不過,我們可以利用update-rc.d命令更便利地進行:

sudo update-rc.d cron defaults # 按照預設支援的執行級別建立軟連結
sudo update-rc.d cron remove   # 刪除軟連結

 

避免使用/etc/rc.local

樹莓派官網上給出了修改/etc/rc.local的方法,來在樹莓派開機時執行使用者自定義的任務。比如在該檔案中執行date命令:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# time
date > /tmp/rc.local.log

exit 0

但這種啟動方式不推薦。/etc/rc.local是在系統初始化的末尾執行的一個指令碼。如果把太多的任務加入到這個指令碼中,不但會拖慢開機的速度,還會造成管理上的混亂。因此,/etc/rc.local往往只用於修改一些在啟動過程需要設定的引數,而不涉及具體的任務啟動。如果想隨開機啟動某些服務,應該避免使用/etc/rc.local。

 

總結

本章主要介紹了用cron實現樹莓派上的任務規劃,以及用多種方式來實現開機啟動程式。

 

歡迎閱讀“騎著企鵝採樹莓”系列文章 

相關文章