Skip to content

本小节介绍程序内置 Lua 解释器,包含一个常用工具库和 Obcsapi 一些内部方法。Bash 脚本主要用于调用一些二进制程序,如 curl ,jq 。建议使用 Lua 处理文字,进行更多操作,借助工具库,可以很轻松的处理 json ,发送 http 。比 Bash 更容易写,而且也可以自己写 Lua 模块,进行引用。

  1. 工具库 gopher-lua-libs 包含 http 请求,文件读写,数据库连接等工具。使用见对应模块的 README.md 。我克隆了一份 https://gitee.com/kkbt/gopher-lua-libs
  2. Obcsapi 方法 通过 local app = require("app") -- 导入 obcsapi 模块

Obcsapi 支持的方法和对应的函数名

go
var appExports = map[string]lua.LGFunction{
	"AppendDailyText":    AppendDailyText,    // 日志新增文本
	"AppendDailyMemos":   AppendDailyMemos,   // 日志新增 memos
	"AppendText":         AppendText,         // 指定文件添加文本
	"GetFileText":        GetFileText,        // 获取指定文件内容,返回字符串
	"CoverStoreTextFile": CoverStoreTextFile, // 覆盖指定位置文件 纯文本使用
	"GetTodayDaily":      GetTodayDaily,      // 获取今日日记 md 文件字符串 // 每天凌晨 00:00 - 03:59  判断为 today daily 为 昨天的日志

	"TimeFmt":  TimeFmt,  // 时间格式化
	"SendMail": SendMail, // 发送邮件

	// KVDB
	"KVGet": KVGet,
	"KVSet": KVSet,
}

参数和返回值见源码 server/command/luaLibApp.go 更多示例见 server/script/*.lua

使用

指令模式

当输出为 O: Command 开头时,可执行 Bash 脚本。如 O: Command echo "Hello,World!" 或者 O: Command bash sh/example.sh 。程序会收集标准输出并返回前端。 输出为 O: Lua 开头时,执行 lua 脚本。如 O: Lua script/hello.lua 。程序会使用内置解释器运行,可以使用一些内置参数,模块等等。必须返回一个字符串,程序会收集 return 的字符串,返回给前端。 其余情况,程序会将字符串内容直接返回前端。

表单输入

程序默认使用 script/form.lua 处理表单,可以修改以满足更多需求

定时任务

配置中 cron 字段,可配置定时任务。任务包含:

  1. 提醒任务
  2. 运行 script/cron.lua (如果监测到这个文件存在)

可以自行在 cron.lua 中编写代码,判断时间,更灵活的执行各种定时任务。

/api/runner/*path 路径使用

POST/GET /api/runner/*path 路径可执行脚本 如

配置文件声明验证和执行脚本 ,以 /api/runner/demo 路径为例。默认使用 token/token100.json 文件进行验证,声明后此路径使用 token/token100.json 进行验证。

配置 config.yaml

yaml
...
### Lua  /api/runner/*path 配置 非常危险
/api/runner/demo: token/token100.json
/api/runner/demo_script: scrpt/api-runner-demo.lua
...

确保配置中文件都存在并且格式语法等正确,然后构造请求

http
POST {{host}}/demo?x=1&token=100
Authorization: demo-auth
Token: {{token1}}
Content-Type: application/application/json

{"a":"a str"}

服务器处理请求,验证通过后。传入给 Lua 脚本 app_input 变量。数据示例如下,格式为字符串。内容可以被解析为 JSON ,使用库即可处理为 Lua table 格式。

json
{
  "headers": {
    "Accept-Encoding": "gzip, deflate",
    "Authorization": "xxx",
    "Connection": "close",
    "Content-Length": "13",
    "Content-Type": "application/application/json",
    "Token": "8IuEzCmgZyNg5Wu1UPVUt32GuDMXPi0q",
    "User-Agent": "vscode-restclient"
  },
  "params": {
    "x": "1",
    "token": "100"
  },
  "request": {
    "method": "POST",
    "body": "{\"a\":\"a str\"}"
  },
  "responseStatusCode": 200,
  "processingTimeMs": 0,
  "clientIP": "127.0.0.1",
  "requestPath": "/api/runner/demo",
  "timestamp": 1696218554
}

Lua 脚本最后必须返回一个字符串,否则会返回 nil 。如果第一个字符为 { ,请求的响应头为 json ,否则为 plain 。

示例

下面给出示例

lua
--- app 为 obcsapi 模块
--- 本示例为 使用 app 调用 obcsapi 的添加到 memos 的示例

local app = require("app") -- 导入 obcsapi 模块
local test = require("test")

print(app_input) -- 从前端传来的参数
-- 带有异常处理的 obcsapi app 调用
print("AppendDailyText")
local err1 = app.AppendDailyText(app_input)
if err1 then
    error(err1)
end

print("AppendDailyMemos")
local err2 = app.AppendDailyMemos(app_input)
if err2 then
    error(err2)
end


-- local err3 = test.ErrorTest()
-- print(err3)
-- if err3 then -- 等于  if err6 ~= nil then
--     error(err3) -- 打印错误信息并终止
-- end

--- 引入自定义 lua 模块写法
local utils = require("script/utils")
local ans = utils.add(2,3)
---

result = "This is a lua result to obcsapi-web , 输入的内容是 "..app_input -- Lua 拼接字符串

return result

用于处理 Jsonscheme 自定义表单传给后端的 json 数据, server/script/form.lua 。示例为将表单转为字符串进行存储,这是一个通用方法。 如果需要更多方法,可以自定义实现,如对特定的文件进行操作。或者使用 libs 库,进行 http 操作等等。如果有自己的 Lua 模块,也可以使用。

lua
--- 用于处理 前端生成的表单 通用处理方法 会添加到日志中
--- @param app_input string 前端输入的内容,是一个字符串,内容是 json
-- @return string Lua 拼接字符串,最终给前端显示

local app = require("app") -- 导入 obcsapi 模块
local utils = require("script/utils") -- 导入自定义函数工具

-- 打印输入的参数
print(app_input)

-- 尝试 JSON 解析 将 json 解析为 table
local json = require("json")
local result, err = json.decode(app_input)
if err then
    error(err)
end


-- 此处可以做一些事情 
-- 比如 取出 json 中的一些字段做判断,执行不同的函数,或者脚本

-- 使用工具库 table_to_string 将 table 转为字符串
table_str = utils.table_to_string(result)
print(table_str)

ret = "后端返回: 前端输入的内容是 "..app_input -- Lua 拼接字符串
ret = ret.."\n解析 JSON 最终转为字符串结果:\n"..table_str
--- 将结果保存到 memos

local err1 = app.AppendDailyMemos(table_str)
if err1 then
    error(err1)
end

return ret.."\n并且保存到 memos 中" -- 返回结果,供给前端显示

危险行为

前端输入

---runlua
print("xxx")
return "非常危险"

后端会将字符串加载为 Lua 函数,并运行。非常危险,谨慎使用。使用不当可能对数据安全与服务器安全造成威胁。默认未启用,但是给出示例。

lua
--- 运行前端传入的 Lua 脚本
--- 非常危险 

local func1 = loadstring(app_input)
local result = func1()
return result