树莓派(Raspberry Pi)使用Shell编写的极简Service
树莓派(Raspberry Pi)运行的系统是基于Debian的,不仅可以运行Shell,还支持systemd和docker,可以编写一个简单的服务,让其在启动时运行,执行一些自动化的操作。这里在RaspPi Zero W上使用shell、systemd和Docker 18.06.1完成,详细步骤介绍如下。
1、初始化系统
从树莓派官网(https://www.raspberrypi.org/)下载镜像,烧写到SD卡(我用Etcher)。
- 下载:https://www.raspberrypi.org/downloads/raspbian/
- 福利:一个开源的超好用的SD卡/U盘烧写工具
将SD卡插入树莓派,加电启动。
登录使用:pi,raspberry。
如果想要通过ssh远程操作,还需要安装和启用sshd服务开机启动(下面介绍)。
当然,首先是要开通WiFi,能够联网。
2、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服务(或者需要重启树莓派)。
联网成功后,执行软件版本更新操作。如下:
sudo apt update && sudo apt upgrade -y
3、编写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 |hengtongyoule.com/ 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=www.gcyl152.com"$PID
}
#=======================
status() {
now=`date '+%Y-%m-%d %H:%M:%S'`
echo "$now Service status ssht."
ps -aux | grep "sshp.worker"www.jrgjze.com| grep -v grep
}
case "$1" in
start) start ;;
stop) stop ;;
restart) restart ;;
status) status ;;
*)
echo "Usage:www.michenggw.com www.dfgjpt.com (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,可以查看输出的信息。
可以修改上面的脚本,添加自己的日志信息输出。
4、Docker安装
也可以把任务放到Docker中运行。我这里用于创建一个Nginx服务,然后运行pac信息提供者,为iPhone等设备提供网络配置参数时使用。
获取docker自动安装脚本并执行:
wget https://www.ysyl157.com 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文件放到该发布目录下。
6、测试可用性
现在,可以测试一下,上面建立的服务是否可用。
使用浏览器
打开setting页面,进入网络设置,勾选sokcs5,填入上面的pac地址,勾选dns over https等选项。
输入任何想要访问的地址,等待奇迹出现。
使用iPhone
进入setting,选择网络设置,里面有个“自动”选项,填入上面的pac地址。
7、小结
编写一个Linux服务还是有一些难度的,上面提供了一个极简的框架。
树莓派体积虽小,运行一些控制性服务也是足够了,关键是功耗足够低,还没有任何噪音。
一些定期执行的任务,如缩时摄影、温湿度监测、自动浇水等等有趣的事都可以使用上面的机制来完成。
8、更多参考
- 使用shell编写的极简Ubuntu Service
- AutoSSH-增强ssh的用法【英】
- SSH 命令行参数详解【英】
- vi、vim、nano如何退出?
- wget 持续下载确保完成
- scp实现断点续传的方法
- 使用shell编写的极简WatchDog
树莓派(Raspberry Pi)使用Shell编写的极简Service的更多相关文章
- 用树莓派Raspberry Pi和Micro:bit做一个自拍器
在这个项目中,我们将使用Python来构建一个由Micro:bit触发树莓派Raspberry Pi和相机模块的自拍器.这是开始使用硬件和简单文本编程的好方法. 我们将学习: 如何设置Raspberr ...
- 树莓派(Raspberry Pi 3) - 系统烧录及xshell连接
树莓派(Raspberry pi)是一块集成度极高的ARM开发板,不仅包含了HDMI,RCA,CSI,HDMI,GPIO等端口,还支持蓝牙以及无线通信.由于 Raspberry Pi 几乎是为 Lin ...
- 树莓派(Raspberry Pi)搭建简单的lamp服务
树莓派(Raspberry Pi)搭建简单的lamp服务: 1. LAMP 的安装 sudo apt-get install apache2 mysql-server mysql-client php ...
- 树莓派(raspberry pi)学习4: 更改键盘布局(转)
树莓派(raspberry pi)用了几次后,发现键盘老是按错,一些字符打不出来或打错 这个问题,折腾我半天.还是把心得分享一下吧 上网查,发现是键盘布局不对,树莓派(raspberry pi)是英国 ...
- 外网登录访问树莓派 Raspberry Pi
外网登录访问树莓派 Raspberry Pi 本地的树莓派 Raspberry Pi,只能在局域网内访问,怎样从公网也能登录访问树莓派 Raspberry Pi? 本文将介绍具体的实现步骤. 1. 准 ...
- 树莓派raspberry pi配置
(1)国际化语言 树莓派初装系统之后,首次启动会出现“raspi-config”工具,如下图:(若不是初次启动,在命令模式下,请输入 sudo raspi-config 命令,即可调出此界面.若在图形 ...
- 树莓派(raspberry pi)学习11: 将树莓派变成一个Web服务器(转)
将树莓派变成一个Web服务器,通过访问网页,就可以控制树莓派,比如:查看摄像头\开灯等等. 一想到Linux Web服务器,我们首先想到的是,Apache + MySql + Php. 树莓派可以安装 ...
- 做一个树莓派Raspberry Pi拍立得
用树莓派Raspberry Pi打造一台拍立得,作法如下: 材料:树莓派+数字相机模块+热敏打印机 因为打印机所需电流较高,所以电源供应器的规格需要5V 3A以上. 再找一个稳定的电源以及够大的外壳装 ...
- VLOG丨树莓派Raspberry Pi 3安装PLEX并挂载USB硬盘打造最牛的微型家庭影音服务器2018
视频介绍 树莓派3安装目前最流行的PLEX服务器,实现既能最大限度降低功耗,也能随时随地观看分享影片. 一.在树莓派下安装PLEX媒体服务器 1.在终端,将你的树莓派更新至最新 sudo apt up ...
随机推荐
- Thrift序列化与反序列化
Thrift序列化与反序列化的实现机制分析 Thrift是如何实现序死化与反序列化的,在IDL文件中,更改IDL文件中的变量序号或者[使用默认序号的情况下,新增变量时,将新增的变量不放在IDL文件的结 ...
- Telnet服务器和客户端请求处理
Telnet服务器和客户端请求处理 本文的控制台项目是根据SuperSocket官方Telnet示例代码进行调试的,官方示例代码:Telnet示例. 开始我的第一个Telnet控制台项目之旅: 创建控 ...
- Java 集合的简单理解
集合(容器) Java的集合类分别是Collection接口和Map接口派生而来. Collection接口 对于实现Collection接口的子类,都会实现Collection接口中抽象方法,所以他 ...
- 在tomcat8.0.x和tomcat9.0.x之间么突然冒出个tomcat 8.5
Apache Tomcat 8 (8.5.38) - Documentation Indexhttps://tomcat.apache.org/tomcat-8.5-doc/index.html to ...
- a标签中的onclick和href的使用
onclick和href 链接的 onclick 事件被先执行,其次是 href 属性下的动作(页面跳转,或 javascript 伪链接): 假设链接中同时存在 href 与 onclick,如果 ...
- vue-cli 上传图片上传到OSS(阿里云)
https://help.aliyun.com/document_detail/32068.html?spm=5176.doc32069.6.304.Qc4SUs(看) https://help.al ...
- C# Note28: Dispatcher类
在项目中也是经常用到: 刚见到它时,你会想:为什么不直接使用System.Windows命名空间下的MessageBox类,何必要这么麻烦?(认真分析看它做了什么,具体原因下面解释) 主要介绍的方法: ...
- Java8 Hash改进/内存改进
又开新坑o(*≧▽≦)ツ讲讲几个Java版本的特性,先开始Java8, HashMap的改进 HashMap采用哈希算法,先使用hashCode()判断哈希值是否相同,如果相同,再使用equals() ...
- 用Python来操作redis 以及在Django中使用redis
什么是Redis? Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值可以包 ...
- “耐撕”团队 2016.03.31 站立会议
1. 时间: 19:30--19:50 共计20分钟. 2. 成员: Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客:ht ...