利用nohup命令创建启动服务

[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#opkg -d usb install /mn
t/sda1/ipk/coreutils_8.16-1_ramips_24kec.ipk
Installing coreutils (8.16-1) to usb...
Configuring coreutils.
[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#opkg -d usb install /mn
t/sda1/ipk/coreutils-nohup_8.16-1_ramips_24kec.ipk
Installing coreutils-nohup (8.16-1) to usb...
Configuring coreutils-nohup.

后面的&是后台运行
Linux shell中有三种输入输出,分别为标准输入,标准输出,错误输出,分别对应0,1,2

ps命令无法看到nohup的job,用jobs -l
 

用nohup执行python程序时,print无法输出
nohup python test.py > nohup.out 2>&1 &
发现nohup.out中显示不出来python程序中print的东西。
这是因为python的输出有缓冲,导致nohup.out并不能够马上看到输出。
python 有个-u参数,使得python不启用缓冲。
nohup python -u test.py > nohup.out 2>&1 &
 
创建启动服务

/etc/init.d/wechat

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org START=10
STOP=15 start() {
echo "wechat start" >> /mnt/sda1/temp/log
date -R >> /mnt/sda1/temp/log
nohup python -u /mnt/sda1/projects/openwrtpytest/utils/webhelper.py 2>>/mnt/sda1/temp/log 1>>/mnt/sda1/temp/log & # commands to launch application
} stop() {
echo "wechat stop" >> /mnt/sda1/temp/log
date -R >> /mnt/sda1/temp/log
# commands to kill application

  

chmod 777 /etc/init.d/wechat
启动

/etc/init.d/wechat start

注意wechat里面的\r\n要换成linux下的\n,不然会出错

如果重复启动后报错端口被占用,要先把原先的进程杀掉

error: [Errno 125] Address already in use
[root@PandoraBox:/mnt/sda1/projects/openwrtpytest/utils]#netstat -atpn | grep 8001
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 2626/python

kill 2626

 
webhelper.py
from wsgiref.simple_server import make_server
from wechat import app PORT = 8001
httpd = make_server('', PORT, app)
httpd.allow_reuse_address = True
httpd.serve_forever()

 wechat.py

#!/mnt/sda1/opkg/usr/bin/python
#coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import time
from flask import Flask, request,make_response,render_template
import hashlib
import xml.etree.ElementTree as ET
import loghelper
import traceback
import requests
import os
import pprint
import uniout
import apihelper
import yaml
import pickledb app = Flask(__name__)
app.debug=True
logger = loghelper.create_logger(r'/mnt/sda1/temp/log')
app_root = os.path.dirname(__file__)
templates_root = os.path.join(app_root, 'templates/reply_text.xml')
api = apihelper.ApiHelper()
cachefpath='../data/cache.db'
cachedb = pickledb.load(cachefpath,True) @app.route('/',methods=['GET','POST'])
def wechat_auth():
msg = "funcname : %s , request.args : %s" % (__name__ ,request.args)
logger.info(msg)
response = make_response("")
try:
if request.method == 'GET':
token='weixintest'
data = request.args
pprint.pprint( "Request get data:",data)
signature = data.get('signature','')
timestamp = data.get('timestamp','')
nonce = data.get('nonce','')
echostr = data.get('echostr','')
s = [timestamp,nonce,token]
s.sort()
s = ''.join(s)
if (hashlib.sha1(s).hexdigest() == signature):
response = make_response(echostr)
else:
response = make_response("Not Valid!")
else:
rec = request.stream.read()
print "Request post data:",rec
xml_rec = ET.fromstring(rec)
datadict = get_replydata(xml_rec)
pprint.pprint(datadict)
render = render_template("reply_text.xml",dict=datadict)
response = make_response(render)
#xml_rep = get_response(xml_rec)
#response = make_response(xml_rep)
response.content_type='application/xml;charset=utf-8'
except Exception,e:
type =xml_rec.find("MsgType").text
tou = xml_rec.find('ToUserName').text
fromu = xml_rec.find('FromUserName').text
datadict = {"to":fromu,"from":tou,"time":str(int(time.time())),"type":type,"msg":e.message}
render = render_template("reply_text.xml",dict=datadict)
response = make_response(render)
# log the exception
err = "exception : %s , %s" % (e.message ,traceback.format_exc())
logger.exception(err)
finally:
#pprint.pprint( request.__dict__)
pprint.pprint( response.__dict__)
return response def get_replydata(xml_rec):
'''
import xml2dict
xml = xml2dict.XML2Dict()
r = xml.fromstring(textdata)
r.get('xml').get('FromUserName').get('value')
'''
type =xml_rec.find("MsgType").text
tou = xml_rec.find('ToUserName').text
fromu = xml_rec.find('FromUserName').text
datadict = {"to":fromu,"from":tou,"time":str(int(time.time())),"type":type,"msg":""}
if type == 'image' or type == 'voice':
dmedia_id = xml_rec.find('MediaId').text
purl = xml_rec.find('PicUrl').text
fname = xml_rec.find('CreateTime').text
import urllib
urllib.urlretrieve(purl,'/mnt/sda1/data/image/%s.jpg' % fname)
print purl
elif type == 'location':
locx = xml_rec.find('Location_X').text
locy = xml_rec.find('Location_Y').text
scale = xml_rec.find('Scale').text
location = xml_rec.find('Label').text
wjdu="%s,%s" % (locx,locy)
data = api.location(wjdu)
datadict["msg"]=data
else:
content = xml_rec.find("Content").text
data = get_replytext(content)
datadict["msg"]=data
print datadict.get("msg")
return datadict def get_replytext(content):
content = content.strip()
print 'enter content :',content
cvalue = cachedb.get(content)
cvalue =None
if cvalue<>None:
print 'get it from cache'
data=cvalue
else:
if content.lower().startswith("ip"):
content=content.replace("ip","").strip()
data = api.ip(content)
elif content.startswith(u"航班"):
data=api.airline(content)
elif content.startswith(u"火车"):
data=api.train(content)
elif content.startswith(u"翻译"):
data=api.translator(content)
elif content.startswith(u"手机"):
data=api.mobile(content)
elif content.startswith(u"简体") or content.startswith(u"繁体"):
data=api.tradition(content)
elif content.startswith(u"汇率"):
data=api.huilv(content)
else:
data = api.weather(content)
cachedb.set(content,data)
return data if __name__ == '__main__':
path='../conf/test.yaml'
with open(path) as f:
x=yaml.load(f)
textdata = x.get('textdata')
wxlink = x.get('wxlink')
r=requests.get(wxlink)
print r.text
r=requests.post(wxlink,textdata)
print r.text

这里实现了查询航班,火车,汇率,中英文翻译,简繁体转换,查询当前IP,手机所在地的功能

代码放在github上
https://github.com/sui84/openwrtpytest

另外pandorbox上的python安装文件为了可以运行有些改动,放在这里

https://github.com/sui84/PandorboxPython27
 

Openwrt路由器上开发微信公众号应用的更多相关文章

  1. 苹果手机上开发微信公众号(wap)遇到的问题解决方法

    1.样式 苹果 手机会自行强制css样式,比如input会变得面目全非,你可以加上input{-webkit-appearance: none;}恢复原貌! 2.jquery的live错误,苹果手机上 ...

  2. NodeJs 开发微信公众号(五)真实环境部署

    在测试环境下开发完成代表着你离正式上线的目标不远了.接下来本章就主要谈一谈把测试环境的公众号升级为正式的公众号. 服务器和域名 目前为止我们只是在自己的电脑上完成了测试环境.真实的线上环境当然需要自己 ...

  3. vue+node.js+webpack开发微信公众号功能填坑——v -for循环

    页面整体框架实现,实现小功能,循环出数据,整体代码是上一篇 vue+node.js+webpack开发微信公众号功能填坑--组件按需引入 修改部门代码 app.vue <yd-flexbox&g ...

  4. vue+node.js+webpack开发微信公众号功能填坑——组件按需引入

    初次开发微信公众号,整体框架是经理搭建,小喽喽只是实现部分功能,整体页面效果 整个页面使用两个组件:布局 FlexBox,搜索框 Search,demo文档 http://vue.ydui.org/d ...

  5. 使用vue开发微信公众号下SPA站点的填坑之旅

    原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...

  6. Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装

    在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...

  7. Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发

    接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...

  8. Spring Boot 开发微信公众号后台

    Hello 各位小伙伴,松哥今天要和大家聊一个有意思的话题,就是使用 Spring Boot 开发微信公众号后台. 很多小伙伴可能注意到松哥的个人网站(http://www.javaboy.org)前 ...

  9. vue开发微信公众号--开发准备

    由于工作项目的原因,需要使用vue开发微信公众号,但是这种微信公众号更多是将APP套了一个微信的壳子,除了前面的授权和微信有关系以外,其他的都和微信没多大的关系了,特此记录 开发流程 首先需要在电脑上 ...

随机推荐

  1. 启迪链网通证经济共同体:柏链教育&火聘online推出区块链行业人才“一门式”服务

    近日,启迪链网通证经济共同体旗下两个节点成员柏链教育与火聘online,达成节点间的合作,据悉本次合作是采用共同体的生态共建模式,柏链教育与火聘online共享企业端岗位需求的大数据,然后有针对性的开 ...

  2. AX导出excel设置格式

    今天在AX2009里面写一个导出EXCEL,没有模版,这是第一次碰到,之后写完之后发现导出的数据格式不对. 到处取经之后得到一下结果: 定义一个 Com   range; SysExcelCells  ...

  3. Relative Sort Array

    Relative Sort Array Given two arrays arr1 and arr2, the elements of arr2 are distinct, and all eleme ...

  4. python模块之openpyxl

    这是一个第三方库,可以处理xlsx格式的Excel文件.pip install openpyxl安装.如果使用Aanconda,应该自带了. 读取Excel文件 需要导入相关函数. from open ...

  5. Flutter Animation AnimatedBuilder

    Flutter AnimatedBuilder 创建动画的widget Key key, @required Listenable animation, @required this.builder, ...

  6. 笔谈OpenGL ES(一)

    现在图形类.视频类app越来越多,学习OpenGL ES是很有必要的,作为程序员是有必要做技术积累的.现在做播放器开发的工作,正好也涉及这块,那就好好学一学. CSDN上有套教程不错,OpenGL E ...

  7. ceph luminous版部署bluestore

    简介 与filestore最大的不同是,bluestore可以直接读写磁盘,即对象数据是直接存放在裸设备上的,这样解决了一直被抱怨的数据双份写的问题 Bluestore直接使用一个原始分区来存放cep ...

  8. elementUI——主题定制

    需求: 设计三套主题色+部分图标更换: 实现方式汇总: 1.传统做法,生成多套css主题包,切换link引入路径切换href实现,参考网站:http://jui.org/: <link id=& ...

  9. Python学习日记(四) 集合和元祖

    元祖的特性:是一个只读列表.可以循环.可以切片,修改数据遵循'儿子'不能改但'孙子'可能可以改. iterable:可迭代对象(元祖.列表.字串.集合) 元祖宣告方式: tu = (1,2,3,['a ...

  10. 自制php操作mysql工具类(DB.class.php)

    DB.class.php <?php class DB{ //主机地址 var $host; //用户名 var $username; //密码 var $password; //数据库名 va ...