由于项目需求+实际条件限制,需要在某台设备上运行一个python小程序,在工业机器人和云服务器之间实现信息转发的功能。因为机器人也需要通过路由器认证连接校园网,出于简化设备的考虑(不想每次跑程序还得开电脑),我决定尝试在路由器上运行这个程序。
本人纯小白,不熟悉linux/openwrt,也是第一次倒腾路由器,怕多生周折就没有自己刷固件,直接买了校园网认证路由器。后面的过程大多参考网上的教程。在此总结和记录一下这个过程,备忘,也希望能对其他有相同需求的朋友提供一点帮助。
任务:1.挂载U盘(因为路由器本身的空间很小)
2.安装Python,
3.设置python程序开机自动后台运行(如果不能自启动那它就失去了灵魂)
工具:winscp: 文件管理
putty:命令行控制
diskgenius:格式化U盘
通过putty登录路由器,命令行输入指令df -h能看到磁盘容量和使用情况,插入U盘后多出了以G为单位的磁盘空间,显然就是我们挂载的U盘了。
注意:列表里面Mounted on指示的位置才是挂载的位置,也就是U盘里面文件所在的位置。
一开始我是按照按默认选项格式化的U盘,路由器也能识别出来,但是后面安装Python的时候报了错(见下图)。谷歌了一下错误信息,有个类似的说是因为fat分区不支持Linux符号链接,需要用ext3/4的格式。重新格式化U盘后再插上,这次居然直接不识别了,尴尬o(╯□╰)o
后来看这个路由器的设置页面(192.168.1.1)上有设置挂载点的功能,这个功能我没琢磨明白,因为我设置之后好像也没啥变化。但是看到设置文件系统的下拉框有几个默认选项:sqashfs、vfat、exfat。抱着试一试的心态,就把U盘格成了exfat格式,后面就没有出现问题了(其实我现在有点怀疑上面的错误是由于我安装过程的操作不对造成的,但是也懒得再用原来的文件格式再试一次了)
通过winscp连接路由器,找到/etc/opkg.conf文件,将文件内容修改为:
dest root /
dest ram /tmp
lists_dir ext /var/opkg-lists
option overlay_root /overlay
# notice
dest usb /mnt/sdb1/opkg
arch all 100
arch ramips_24kec 200
arch ramips 300
arch mips 400
arch unkown 500
src/gz barrier_breaker_base http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/base
src/gz barrier_breaker_luci http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/luci
src/gz barrier_breaker_management http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/management
src/gz barrier_breaker_oldpackages http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/oldpackages
src/gz barrier_breaker_packages http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/packages
src/gz barrier_breaker_routing http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/routing
src/gz barrier_breaker_telephony http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/telephony
#notice下面的
dest usb /mnt/sda1/opkg
就是指定变量
usb
为外置存储路径
/mnt/sda1/opkg
。保存文件后到命令行执行
opkg update
更新完成后就可以使用opkg -d usb install xxx
即可将程序安装至/mnt/sda1/opkg
# 先需要安装libc,需要下载下来安装
## 建立文件夹
mkdir -p /mnt/sda1/opkg/src
cd /mnt/sda1/opkg/src
wget http://downloads.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/base/libc_0.9.33.2-1_ramips_24kec.ipk
## 安装libc,最好安装到根下
opkg install libc_0.9.33.2-1_ramips_24kec.ipk
# 接着安装Python
opkg -d usb install libreadline
opkg -d usb install python
opkg -d usb install python-json
opkg -d usb install python-curl
opkg -d usb install python-openssl
# 路径
export PATH=$PATH:/mnt/sda1/opkg/usr/bin
echo 'export PATH=$PATH:/mnt/sda1/opkg/usr/bin' >> /etc/profile
# 别名
echo "alias opintall='opkg -d usb install'" >> /etc/profile
安装完成后可以命令行输入python然后进入python环境(出现>>>标志)或者python XXX.py来执行python程序。
主要参考链接:openwrt路由器安装python教程
路由器的开机启动项可以在路由器控制页面的“启动项”里设置启动脚本并应用。它本质上是修改路由器的/etc/rc.local文件,所以可直接通过winscp来修改这个文件。为了能够查看后台代码的运行状态,我们安装了nohup,安装方法见链接点击打开链接
将下面这句代码添加到exit 0之前:
nohup python /mnt/sda1/myProgram/app.py >/mnt/sda1/myProgram/output.txt 2.&1 &
这段代码表示后台用python运行app.py,输出保存到output.txt。其中:
- >/mnt/sda1/myProgram/output.txt指定输出重定向的地址(运行前要通过winscp在这个地址上新建文件,
否则会保存到默认位置),如果不想保存输出可以定向到/dev/null,这是各地址相当于系统垃圾桶,输出的信息直接丢弃
- 2>&1 表示系统错误输出(用2代表)stderr的重定向方式和标准输出(用1代表)stdout的方式一样。 &1表示和1一样
- 最后一个&表示程序在后台运行。
保存rc.local文件后重启,查看前面设置的output.txt文件,发现输出了一个错误信息:找不到python。原因是在执行这个脚本的时候,
python的环境变量还没加载,因此要在执行python程序之前先加载环境变量。在etc/rc.local文件里面添加的指令改为:
PATH=$PATH:/mnt/sda1/opkg/usr/bin
nohup python /mnt/sda1/myProgram/app.py >/mnt/sda1/myProgram/output.txt 2.&1 &
修改后程序可以运行了,但是并没有如预期输出print的信息。这是因为python的输出有缓冲,导致nohup.out并不能够马上看到输出。
可以为python添加-u参数,使得python不启用缓冲。
PATH=$PATH:/mnt/sda1/opkg/usr/bin
nohup python -u /mnt/sda1/myProgram/app.py >/mnt/sda1/myProgram/output.txt 2.&1 &
主要参考链接:
python服务器后台运行;nohup相关指令;openwrt开机启动过程分析+添加自启动脚本