openwrtluci开发教程系列1lua调用shell命令
本人从事网关路由器开发10多年,对openwrt系统及luci页面、lua语言较为了解,从今天开始将坚持每天发布一篇与luci/lua相关的开发教程,内容可短可长,但是每一篇我都会尽量做到表述正确、增加知识点。
我不会花大量的篇幅去讲解什么是lua、什么是luci,这些初级知识还请自行百度即可;
第一篇开始:lua语言执行shell命令为什么需要用lua执行shell
在luci页面上当用户提交时,为了获取到用户的输入数据,并基于这些数据执行某些指令达到存储、通知等目的,就可以在luci页面中直接调用shell指令,在openwrt+luci的开发环境下,有多种方法来实现lua执行shell指令的方法
方法1:os.execute(cmd)
lua的核心库os中自带execute函数,可以直接调用,缺点:此函数返回的是命令执行后的状态码,无法获取命令执行的输出结果,如果不需要知道他的输出结果的话可以直接调用这个方法,在命令的后面加上&可以实现后台调用的效果
示例:os.execute("echo "nihaoa " > /tmp/hehe ")
方法二:io.popen()
此函数会返回一个文件描述符,是核心库io的函数,使用完成后别忘记调用close方法,示例
local t = io.popen("svn help") local a = t:read("*all") io.close(t) --或者 t:close() print(a) --a返回一个字符串,内容是svn help的内容
方法三:luci.util.exec(cmd)和luci.sys.exec(cmd)
这两个方法是luci库中提供的,如果你在非luci环境下调用这两个函数,就需要在文件头上require("luci.util") require("luci.sys")
这两个函数都可以实现获取到shell脚本执行后的输出结果,这一点就好于os.execute
经过查看luci的代码,发现luci.sys.exec其实就是对luci.util.exec的再次调用而已
如下是/usr/lib/lua/luci/sys.lua的片段module "luci.sys" exec = luci.util.exec总结
经过对比以上三个方法,os.execute较为简单,直接返回结果码不返回命令执行的输出,io.popen()是很低层的函数,调用这个稍微麻烦,而第三种方法其实就是对io.popen的再次封装,完全可用这两个方法替代前两种。