樹莓派(Raspberry Pi)使用Shell編寫的極簡Service

樹莓派(Raspberry Pi)運行的系統是基於Debian的,不只能夠運行Shell,還支持systemd和docker,能夠編寫一個簡單的服務,讓其在啓動時運行,執行一些自動化的操做。這裏在RaspPi Zero W上使用shell、systemd和Docker 18.06.1完成,詳細步驟介紹以下。html

一、初始化系統

從樹莓派官網(https://www.raspberrypi.org/)下載鏡像,燒寫到SD卡(我用Etcher)。nginx

將SD卡插入樹莓派,加電啓動。web

登陸使用:pi,raspberry。docker

若是想要經過ssh遠程操做,還須要安裝和啓用sshd服務開機啓動(下面介紹)。shell

固然,首先是要開通WiFi,可以聯網。vim

二、WiFi 設置

Wifi AP設置,使用命令 「nano /etc/wpa_supplicant/wpa_supplicant.conf」 編輯配置文件,參照下面的方法添加WiFi熱點:瀏覽器

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
	ssid="HiWiFi_xxxxxx"
	psk="mypassword"
}

創建服務須要使用靜態地址。修改文件dhcpcd(使用nano /etc/dhcpcd),編輯以下內容:服務器

interface wlan0
noipv6rs
noipv6
static ip_address=192.168.199.190
static routers=192.168.199.1
domain_name_servers=192.168.199.1 8.8.8.8 9.9.9.9

將上面的IP地址和DNS改成本身的,其中8.8.8.8/9.9.9.9爲公共的DNS服務地址,不需修改。網絡

重啓dhcpcd服務(或者須要重啓樹莓派)。app

聯網成功後,執行軟件版本更新操做。以下:

sudo apt update && sudo apt upgrade -y

三、編寫WatchDog和Service

建立一個本身的目錄,建立下面三個文件:

  • sshp.service,由systemd調用的服務配置文件。
  • sshp.daemon,執行服務控制(啓動、中止、狀態)的腳本文件。
  • sshp.worker,執行服務的任務腳本文件。

文件的內容以下。

3.1 sshp.service文件

[Unit]
Description=Secure Shell server proxy
After=network.target

[Service]
Type=forking
ExecStart=/home/pi/openthings/tutools/sshp.daemon start
ExecStop=/home/pi/openthings/tutools/sshp.daemon stop
TimeoutSec=0
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
Alias=sshp.service

3.2 sshp.daemon文件

#!/bin/sh

echo "SSHP tools."
#=======================
start() {
  now=`date '+%Y-%m-%d %H:%M:%S'`
  echo "$now  Start SSHP worker ..." >> /home/pi/openthings/tutools/sshp.log
  nohup /home/pi/openthings/tutools/sshp.worker &
}

#=======================
stop() {
  PID=`ps -aux | grep "sshp.worker" | grep -v grep | awk -F " " '{print $2}'`
  kill -9 $PID
  echo "Stop SSHP worker, PID="$PID >> /home/pi/openthings/tutools/sshp.log
}

#=======================
restart() {
  echo "Restart Service..."
  Stop
  Start
  echo "Restarted SSHT worker, PID="$PID
}

#=======================
status() {
  now=`date '+%Y-%m-%d %H:%M:%S'`
  echo "$now  Service status ssht."
  ps -aux | grep "sshp.worker" | grep -v grep
}

case "$1" in
  start) start ;;
  stop)  stop  ;;
  restart) restart ;;
  status) status ;;
  *)
    echo "Usage: (start|stop|restart|status)"
    exit 1
    ;;
esac

echo "Service SSHP tools done."
exit 0

3.3 sshp.worker文件

#!/bin/sh
while true; do
  sshpass -p mypassword ssh -o "ExitOnForwardFailure yes" -o "StrictHostKeyChecking no" -y -p 22000 -NgD *:5555 root@myserver
done
  • 這裏僅使用ssh演示worker編寫方法,具體能夠參考:SSH 命令行參數詳解【英】
  • 這裏有個坑是,以服務啓動時的帳戶是root,與當前用戶pi的配置信息和缺省參數是不一樣的。

3.4 設爲啓動時運行

使用下面的命令將剛纔編寫的服務設爲啓動時運行:

sudo systemctl enable sshp.service

查看一下,系統裏的啓動運行服務:

# ls -l /etc/systemd/system/multi-user.target.wants/

total 0
lrwxrwxrwx 1 root root 40 Nov 29  2017 avahi-daemon.service -> /lib/systemd/system/avahi-daemon.service
lrwxrwxrwx 1 root root 41 Nov 29  2017 console-setup.service -> /lib/systemd/system/console-setup.service
lrwxrwxrwx 1 root root 38 Apr 12 05:45 containerd.service -> /lib/systemd/system/containerd.service
lrwxrwxrwx 1 root root 32 Nov 29  2017 cron.service -> /lib/systemd/system/cron.service
lrwxrwxrwx 1 root root 34 Nov 29  2017 dhcpcd.service -> /lib/systemd/system/dhcpcd.service
lrwxrwxrwx 1 root root 34 Dec 25  2017 docker.service -> /lib/systemd/system/docker.service
lrwxrwxrwx 1 root root 35 Nov 29  2017 hciuart.service -> /lib/systemd/system/hciuart.service
lrwxrwxrwx 1 root root 38 Nov 29  2017 networking.service -> /lib/systemd/system/networking.service
lrwxrwxrwx 1 root root 37 Nov 29  2017 nfs-client.target -> /lib/systemd/system/nfs-client.target
lrwxrwxrwx 1 root root 48 Nov 29  2017 raspberrypi-net-mods.service -> /lib/systemd/system/raspberrypi-net-mods.service
lrwxrwxrwx 1 root root 36 Nov 29  2017 remote-fs.target -> /lib/systemd/system/remote-fs.target
lrwxrwxrwx 1 root root 33 Nov 29  2017 rsync.service -> /lib/systemd/system/rsync.service
lrwxrwxrwx 1 root root 35 Nov 29  2017 rsyslog.service -> /lib/systemd/system/rsyslog.service
lrwxrwxrwx 1 root root 40 Apr 12 15:43 sshp.service -> /home/pi/openthings/tutools/sshp.service
lrwxrwxrwx 1 root root 31 Apr 12 12:40 ssh.service -> /lib/systemd/system/ssh.service
lrwxrwxrwx 1 root root 37 Nov 29  2017 sshswitch.service -> /lib/systemd/system/sshswitch.service
lrwxrwxrwx 1 root root 40 Nov 29  2017 triggerhappy.service -> /lib/systemd/system/triggerhappy.service
lrwxrwxrwx 1 root root 47 Dec 25  2017 unattended-upgrades.service -> /lib/systemd/system/unattended-upgrades.service
lrwxrwxrwx 1 root root 40 Mar 24  2018 wifi-country.service -> /lib/systemd/system/wifi-country.service
lrwxrwxrwx 1 root root 42 Apr 12 05:46 wpa_supplicant.service -> /lib/systemd/system/wpa_supplicant.service

3.5 測試服務啓停

使用下面的命令來控制服務。

# 查看服務運行狀態。
sudo systemctl status

# 啓動服務。
sudo systemctl start
# 而後,可使用ps -aux查看ssh進程是否已經啓動。

# 中止服務。
sudo systemctl stop
# 而後,可使用ps -aux查看ssh進程是否已經關閉。

這裏設置了一個日誌文件,爲上面的目錄下sshp.log,能夠查看輸出的信息。

能夠修改上面的腳本,添加本身的日誌信息輸出。

四、Docker安裝

也能夠把任務放到Docker中運行。我這裏用於建立一個Nginx服務,而後運行pac信息提供者,爲iPhone等設備提供網絡配置參數時使用。

獲取docker自動安裝腳本並執行:

wget https://get.docker.io -O docker.sh
sudo chmod docker.sh
./docker.sh

目前,最新的Docker版本是18.09,可是運行時有Bug,暫時尚未解決。

咱們使用18.06.1版。安裝指定的Docker版本:

sudo apt install docker-ce=18.06.1-ce

將版本鎖定,以免apt upgrade時自動升級到最新版本,命令以下:

sudo echo "docker-ce hold" | sudo dpkg --set-selections

測試一下Docker,看看安裝是否成功:

docker info

5 構建PAC服務

pac是什麼?

pac是一種網絡配置的機制,客戶端經過獲取pac文件來自動獲取一系列配置參數,從而對網絡進行初始化設置。

編寫一個pac文件,以下:

function FindProxyForURL(url, host)
{ 
     return "SOCKS 192.168.199.190:5555";
}

pac服務構建

而後,將pac文件放入Web服務器,構建一個文件服務(也能夠動態生成)。

這裏使用Nginx的Docker鏡像來提供服務(注意Nginx有多種Docker鏡像,只有爲樹莓派編譯的才能夠在上面運行)。

運行:

docker run --name nginx -v /home/pi/openthings/web:/usr/share/nginx/www:ro -d -p 80:80 akkerman/rpi-nginx

這個安裝說明運行了後,所編寫的文件並無發佈出來,進去看是由於Nginx缺省路徑爲/var/www/html,而不是/usr/share/nginx/www。能夠修改上面的命令爲:

docker run --name nginx -v /home/pi/openthings/web:/var/www/html:ro -d -p 80:80 akkerman/rpi-nginx

或者執行Exec進入Docker進行修改,以下:

docker exec -it nginx /bin/sh

查看Nginx的service目錄:

cat /etc/nginx/sites-available/default

創建軟鏈接:

ln -s /usr/share/nginx/www /var/www/html

在目錄下,創建一個index.html文件,而後到瀏覽器輸入http://my-raspberrypi-ip,看是否可以發佈出來。

而後,將上面的pac文件放到該發佈目錄下

六、測試可用性

如今,能夠測試一下,上面創建的服務是否可用。

  • 使用瀏覽器

打開setting頁面,進入網絡設置,勾選sokcs5,填入上面的pac地址,勾選dns over https等選項。

輸入任何想要訪問的地址,等待奇蹟出現。

  • 使用iPhone

進入setting,選擇網絡設置,裏面有個「自動」選項,填入上面的pac地址。

七、小結

編寫一個Linux服務仍是有一些難度的,上面提供了一個極簡的框架。

樹莓派體積雖小,運行一些控制性服務也是足夠了,關鍵是功耗足夠低,尚未任何噪音。

一些按期執行的任務,如縮時攝影、溫溼度監測、自動澆水等等有趣的事均可以使用上面的機制來完成。

八、更多參考

相關文章
相關標籤/搜索