树莓派(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服务仍是有一些难度的,上面提供了一个极简的框架。

树莓派体积虽小,运行一些控制性服务也是足够了,关键是功耗足够低,尚未任何噪音。

一些按期执行的任务,如缩时摄影、温湿度监测、自动浇水等等有趣的事均可以使用上面的机制来完成。

八、更多参考

相关文章
相关标签/搜索