主题
OS 操作系统库使用说明
📖 模块概述
OS操作系统库是Lua标准库的一部分,提供了与操作系统交互的核心功能。在LPPLC系统中,该库被扩展以支持工业控制应用的特殊需求,包括高精度时间操作、系统资源监控和进程管理等功能。
主要功能
- ⏰ 时间日期操作和格式化
- 🌍 环境变量读取和设置
- 💻 系统命令执行
- 📁 文件系统基础操作
- 🔄 程序流程控制
- 📊 系统资源监控
- ⏱️ 高精度延时控制
适用场景
- 系统管理和监控脚本
- 日志记录和时间戳生成
- 定时任务和调度系统
- 环境配置和参数管理
- 系统性能监控
- 工业控制时序管理
📚 API参考
📋 函数列表
| 函数名 | 功能描述 | 示例 |
|---|---|---|
os.time([table]) | 获取Unix时间戳或计算指定时间的时间戳 | os.time() |
os.date([format, time]) | 格式化时间戳为可读的日期时间字符串 | os.date("%Y-%m-%d") |
os.clock() | 获取程序运行时间(CPU时间) | os.clock() |
os.getenv(varname) | 获取环境变量的值 | os.getenv("PATH") |
os.execute([command]) | 执行系统命令 | os.execute("ls") |
os.exit([code, close]) | 退出程序 | os.exit(0) |
os.remove(filename) | 删除文件 | os.remove("file.txt") |
os.rename(oldname, newname) | 重命名或移动文件 | os.rename("old.txt", "new.txt") |
os.tmpname() | 生成临时文件名 | os.tmpname() |
时间日期函数
⏰ os.time([table])
获取Unix时间戳或计算指定时间的时间戳。
参数:
table(table, 可选): 包含时间信息的表,包含字段:year: 年份 (必需)month: 月份 1-12 (必需)day: 日期 1-31 (必需)hour: 小时 0-23 (可选,默认12)min: 分钟 0-59 (可选,默认0)sec: 秒数 0-59 (可选,默认0)isdst: 夏令时标志 (可选)
返回值:
number: Unix时间戳(秒)
示例:
lua
-- 获取当前时间戳
local now = os.time()
print("当前时间戳:", now)
-- 计算指定时间的时间戳
local specific_time = {
year = 2024,
month = 12,
day = 25,
hour = 10,
min = 30,
sec = 0
}
local timestamp = os.time(specific_time)
print("圣诞节时间戳:", timestamp)
-- 计算时间差
local start_time = os.time()
-- ... 执行一些操作 ...
local end_time = os.time()
print("操作耗时:", end_time - start_time, "秒")实用例程
lua
mqtt.subscribe(xd,"/sys/thing/property/post_reply/<设备ID>/dlinks_<设备ID>",0)--订阅消息
end)
mqtt.reg(xd,mqtt.DISCONNECTED,function()--注册网络断开事件
print("xd 网络断开")
end
)
mqtt.reg(xd,mqtt.RECVDATA,function(a,b)--注册接收到数据事件
print("收到xd数据:",a,b)
end
)
xd:start()--启动MQTT协议栈
dsfb1=timer.start(600000,function()--启动定时器600秒(10分钟)发布一个数据,测试时1分钟一次
local time1=os.time()-28800
--所有数据用string.format("%011.2f", V)格式化数据(总位数10位,小数2位,lua包含小数),以满足市局平台要求
tb1={
id=plc.dsd(37),version="1.0",sys= {ack= 1}, method="thing.property.post",
params={
ys_wt={time=time1, value= plc.df(6)},--温度
ys_ph={time=time1, value= plc.df(4)},--PH值
ys_turb={time=time1, value=plc.df(8) },--浊度
--ys_pressure={time=time1, value=string.format("%011.2f", plc.d(14)/100) }, --原水压力
ys_momentflow={time=time1, value=plc.df(0) }, --瞬时流量
ys_totalflow={time=time1, value=plc.dd(2) }, --累计流量
}
}把上面的地址、主题、引脚替换成你项目里的即可。
📅 os.date([format, time])
格式化时间戳为可读的日期时间字符串。
参数:
format(string, 可选): 格式化字符串,默认为 "%c"time(number, 可选): Unix时间戳,默认为当前时间
常用格式符:
%Y: 四位年份 (2024)%m: 月份 (01-12)%d: 日期 (01-31)%H: 小时 (00-23)%M: 分钟 (00-59)%S: 秒数 (00-59)%w: 星期几 (0-6, 0为周日)%j: 一年中的第几天 (001-366)
返回值:
string: 格式化后的时间字符串table: 当format为"*t"时返回时间表
示例:
lua
-- 基本时间格式化
print(os.date()) -- 默认格式
print(os.date("%Y-%m-%d %H:%M:%S")) -- 2024-01-31 15:30:45
-- 获取时间表
local time_table = os.date("*t")
print("年份:", time_table.year)
print("月份:", time_table.month)
print("日期:", time_table.day)
-- 自定义格式
print(os.date("今天是%Y年%m月%d日"))
print(os.date("现在是%H点%M分"))
-- 格式化指定时间戳
local timestamp = 1640995200
print(os.date("%Y-%m-%d", timestamp))⏱️ os.clock()
获取程序运行时间(CPU时间)。
返回值:
number: 程序运行的CPU时间(秒)
示例:
lua
-- 测量代码执行时间
local start = os.clock()
-- 执行一些计算密集的操作
for i = 1, 1000000 do
math.sin(i)
end
local elapsed = os.clock() - start
print("计算耗时:", elapsed, "秒")环境变量函数
🌍 os.getenv(varname)
获取环境变量的值。
参数:
varname(string): 环境变量名
返回值:
string: 环境变量值,不存在时返回nil
示例:
lua
-- 获取系统环境变量
local path = os.getenv("PATH")
print("系统PATH:", path)
local user = os.getenv("USERNAME") or os.getenv("USER")
print("当前用户:", user)
-- 检查环境变量是否存在
local temp_dir = os.getenv("TEMP") or os.getenv("TMP") or "/tmp"
print("临时目录:", temp_dir)系统控制函数
▶️ os.execute([command])
执行系统命令。
参数:
command(string, 可选): 要执行的系统命令
返回值:
boolean: 命令执行成功返回truestring: 退出类型 ("exit" 或 "signal")number: 退出码或信号编号
示例:
lua
-- 执行简单命令
local success = os.execute("dir") -- Windows
-- local success = os.execute("ls") -- Linux
if success then
print("命令执行成功")
else
print("命令执行失败")
end
-- 创建目录
os.execute("mkdir logs")
-- 复制文件
os.execute("copy config.txt config_backup.txt")🚪 os.exit([code, close])
退出程序。
参数:
code(number, 可选): 退出码,默认为0close(boolean, 可选): 是否关闭Lua状态机
示例:
lua
-- 正常退出
os.exit(0)
-- 异常退出
if error_condition then
print("发生严重错误,程序退出")
os.exit(1)
end文件系统函数
🗑️ os.remove(filename)
删除文件。
参数:
filename(string): 要删除的文件名
返回值:
boolean: 成功返回true,失败返回nilstring: 错误信息(失败时)
示例:
lua
-- 删除文件
local success, err = os.remove("temp.txt")
if success then
print("文件删除成功")
else
print("删除失败:", err)
end实用例程
lua
print("<名称>")
return
end
file:write(file_data)
file:close()-- 关闭文件句柄
print("<名称>")
end
local function file_read(file_path, file_data)
print("<名称>"..file_path)
local file = io.open(file_path, "r")-- 以读取模式打开文件
local file_data = file:read("*a")
file:close()-- 关闭文件
system.sleep(10)
local success, err = os.remove(file_path)
if success then
print("文件删除成功")
else
print("文件删除失败:", err)
end
return file_data
end
-- 删除文件函数(带错误处理)
local function file_delete(file_path)
-- 检查文件是否存在(可选,更高效的方式)
local file = io.open(file_path, "r")
if not file then把上面的地址、主题、引脚替换成你项目里的即可。
📝 os.rename(oldname, newname)
重命名或移动文件。
参数:
oldname(string): 原文件名newname(string): 新文件名
返回值:
boolean: 成功返回true,失败返回nilstring: 错误信息(失败时)
示例:
lua
-- 重命名文件
local success, err = os.rename("old.txt", "new.txt")
if success then
print("文件重命名成功")
else
print("重命名失败:", err)
end
-- 移动文件
os.rename("temp.log", "logs/temp.log")📄 os.tmpname()
生成临时文件名。
返回值:
string: 临时文件名
示例:
lua
-- 生成临时文件名
local temp_file = os.tmpname()
print("临时文件:", temp_file)
-- 使用临时文件
local file = io.open(temp_file, "w")
file:write("临时数据")
file:close()
-- 使用完后删除
os.remove(temp_file)💡 实用示例
日志记录系统
lua
-- 创建带时间戳的日志函数
function log(level, message)
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
local log_entry = string.format("[%s] %s: %s", timestamp, level, message)
-- 输出到控制台
print(log_entry)
-- 写入日志文件
local log_file = io.open("/spiffs/system.log", "a")
if log_file then
log_file:write(log_entry .. "\n")
log_file:close()
end
end
-- 使用示例
log("INFO", "系统启动")
log("WARNING", "内存使用率较高")
log("ERROR", "网络连接失败")定时任务调度器
lua
-- 简单的定时任务调度器
local scheduler = {}
function scheduler.add_task(name, interval, callback)
scheduler[name] = {
interval = interval,
callback = callback,
last_run = os.time()
}
end
function scheduler.run()
local current_time = os.time()
for name, task in pairs(scheduler) do
if type(task) == "table" and
current_time - task.last_run >= task.interval then
print(os.date("%H:%M:%S") .. " 执行任务: " .. name)
task.callback()
task.last_run = current_time
end
end
end
-- 添加定时任务
scheduler.add_task("数据备份", 3600, function() -- 每小时
print("执行数据备份...")
os.execute("copy data.db backup/data_" .. os.date("%Y%m%d_%H%M%S") .. ".db")
end)
scheduler.add_task("系统监控", 60, function() -- 每分钟
print("检查系统状态...")
-- 检查系统资源使用情况
end)
-- 主循环
while true do
scheduler.run()
os.execute("timeout /t 10 /nobreak > nul") -- Windows延时10秒
end系统信息收集
lua
-- 系统信息收集器
local system_info = {}
function system_info.get_basic_info()
local info = {}
-- 获取当前时间
info.current_time = os.date("%Y-%m-%d %H:%M:%S")
info.timestamp = os.time()
-- 获取环境变量
info.computer_name = os.getenv("COMPUTERNAME") or os.getenv("HOSTNAME")
info.username = os.getenv("USERNAME") or os.getenv("USER")
info.os_type = os.getenv("OS") or "Unknown"
return info
end
function system_info.create_report()
local info = system_info.get_basic_info()
local report_file = "/spiffs/system_report_" .. os.date("%Y%m%d") .. ".txt"
local file = io.open(report_file, "w")
if file then
file:write("=== 系统信息报告 ===\n")
file:write("生成时间: " .. info.current_time .. "\n")
file:write("计算机名: " .. (info.computer_name or "未知") .. "\n")
file:write("用户名: " .. (info.username or "未知") .. "\n")
file:write("操作系统: " .. (info.os_type or "未知") .. "\n")
file:write("时间戳: " .. info.timestamp .. "\n")
file:close()
print("系统报告已生成: " .. report_file)
else
print("无法创建报告文件")
end
end
-- 生成报告
system_info.create_report()文件管理工具
lua
-- 文件管理工具集
local file_utils = {}
function file_utils.backup_file(filename)
local backup_name = filename .. ".backup." .. os.date("%Y%m%d_%H%M%S")
local success, err = os.rename(filename, backup_name)
if success then
print("文件备份成功: " .. backup_name)
return backup_name
else
print("备份失败: " .. err)
return nil
end
end
function file_utils.cleanup_old_files(directory, days)
local cutoff_time = os.time() - (days * 24 * 3600)
-- 这里需要配合其他库来遍历目录
print("清理 " .. days .. " 天前的文件...")
-- 示例:删除旧的日志文件
for i = 1, 30 do
local old_date = os.date("%Y%m%d", os.time() - i * 24 * 3600)
local old_log = "/spiffs/log_" .. old_date .. ".txt"
if i > days then
local success = os.remove(old_log)
if success then
print("删除旧文件: " .. old_log)
end
end
end
end
function file_utils.create_temp_workspace()
local temp_dir = "temp_" .. os.date("%Y%m%d_%H%M%S")
local success = os.execute("mkdir " .. temp_dir)
if success then
print("创建临时工作区: " .. temp_dir)
return temp_dir
else
print("无法创建临时工作区")
return nil
end
end
-- 使用示例
file_utils.backup_file("/spiffs/important_data.txt")
file_utils.cleanup_old_files("logs", 7) -- 清理7天前的文件
local workspace = file_utils.create_temp_workspace()⚠️ 注意事项
- 时区处理:
os.time()和os.date()使用本地时区 - 命令执行安全: 使用
os.execute()时要注意命令注入风险 - 文件操作权限: 确保程序有足够权限进行文件操作
- 跨平台兼容: 系统命令在不同平台上可能不同
- 错误处理: 文件操作可能失败,要适当处理错误情况
例程
系统库(
os.*)提供时间、计时、少量系统交互。下面例程都是可直接下载运行的完整脚本:顶层执行完即结束,不阻塞主循环。注意:固件上os.time/os.date/os.clock一般可用,但os.execute/os.getenv在嵌入式上可能不支持,跨机型使用前先判空(见标准库与机型差异)。
例程 1:给日志/上报加时间戳
适用:全部机型 / 软PLC模拟器 / 上位机 | 依赖模块:os string | 难度:★☆☆
场景:上报 JSON 或写日志时带上当前时间,便于上位机按时间序列展示。
完整代码(可直接下载运行):
lua
local ts = os.date("%Y-%m-%d %H:%M:%S") -- 如 2026-09-25 14:03:05
print("现在:", ts)
-- 自定义格式(小时:分钟)
print("短格式:", os.date("%H:%M"))
-- 取 Unix 时间戳(秒),适合上报
local epoch = os.time()
print("时间戳:", epoch)要点:
os.date(fmt)按格式输出字符串;不传格式返回默认可读串。os.time()返回 Unix 秒数,适合做字段、差值计算。- 格式符:
%Y年%m月%d日%H时%M分%S秒。
验证方法:
- 运行打印形如「现在: 2026-09-25 14:03:05」。
- 「时间戳」为一个递增的整数秒数。
注意事项:
- 设备时钟未校准时,
os.date显示的是出厂默认/未同步时间;需要准确时间得先对时(通常经云平台)。 os.date("*t")返回表(年/月/日...),适合取单个字段做判断。- 嵌入式若未实现
os.time,返回可能是固定值,使用前先type确认。
例程 2:统计一段处理耗时
适用:全部机型 / 软PLC模拟器 / 上位机 | 依赖模块:os | 难度:★☆☆
场景:想知道「读 8 个寄存器 + JSON 编码 + 上报」总共花多少毫秒,定位慢操作。
完整代码(可直接下载运行):
lua
local t0 = os.clock() -- CPU 时间(秒,带小数)
-- 模拟一段工作
local sum = 0
for i = 1, 1000 do sum = sum + math.sqrt(i) end
local dt = os.clock() - t0
print(string.format("耗时 %.3f 秒", dt))要点:
os.clock()返回程序累计 CPU 时间(秒,浮点),适合量算性能。- 与
os.time()(墙钟秒)不同:clock不受睡眠/等待外设影响,更纯粹。 - 差值即为该段耗时。
验证方法:
- 运行打印「耗时 0.0xx 秒」量级的小数值。
- 把循环次数改成 1,耗时明显变小。
注意事项:
os.clock()是 CPU 时间,若脚本大部分时间在com.recv等阻塞等待上,clock几乎不涨——那种要改用os.time()差值。- 长时间运行的累计值可能很大,做差时别溢出(一般 Lua number 够用)。
- 不同固件
clock精度差异大,只在「相对快慢」上有意义。
例程 3:按时间判断保养/到点动作
适用:全部机型 / 软PLC模拟器 / 上位机 | 依赖模块:os plc | 难度:★★☆
场景:设备运行满 30 天提醒保养;或每天 0 点触发一次日统计。用 os.time 计算「距上次保养过了多少秒」。
完整代码(可直接下载运行):
lua
local last_maint = 1700000000 -- 上次保养的 Unix 秒(实际应用从 fdb/云读取)
local now = os.time()
local days = math.floor(os.difftime(now, last_maint) / 86400)
if days >= 30 then
print("已运行", days, "天,请保养")
plc.y(0, 1) -- 例如点亮保养指示灯
else
print("距保养还有", 30 - days, "天")
end要点:
os.difftime(t2, t1)返回两时间戳之差(秒),跨平台安全(不直接相减也行,但用它更稳)。- 秒数转「天」除以
86400。 - 触发后一般要把
last_maint存回fdb/plc区,否则每次都触发。
验证方法:
- 把
last_maint设为 30 天前,days >= 30→ 打印「请保养」并置 Y0。 - 设为 1 天前 → 打印「距保养还有 29 天」。
注意事项:
- 直接用
now - last_maint在大多数平台等于os.difftime,但老平台建议用difftime保兼容。 - 设备时钟漂移/未对时,会让「天数」算错,保养提醒不准。
- 触发后不回写
last_maint,下次运行还会再触发——关键状态要用fdb持久化(见数据存储模块)。
最后更新: 2026-04-26版本: 1.0
函数速查表
下表列出本库全部函数与方法(含尚未单独成节的),点「说明」可跳转到对应小节。签名按通用记法:括号内按顺序列全参数,方括号里的可以省略(不传走默认值),... 表示还可继续传同类参数;h: 开头的是对象方法,先用库级函数拿回句柄再冒号调用。
| 方法与签名 | 作用 | 说明 |
|---|---|---|
os.clock(…) | 返回程序已运行的 CPU 时间(秒) | 本文开头 |
os.date(…) | 按格式输出日期时间(格式以 ! 开头用 UTC) | 本文开头 |
os.difftime(…) | 两个时间戳之差(秒) | 跳转 |
os.execute(…) | 执行一条系统命令 | 本文开头 |
os.exit(…) | 结束脚本/程序 | 本文开头 |
os.getenv(string) | 读取环境变量 | 本文开头 |
os.remove(string) | 删除文件 | 本文开头 |
os.rename(string, string) | 重命名或移动文件 | 本文开头 |
os.setlocale(…) | 设置语言区域(影响日期与大小写规则) | 跳转 |
os.time(…) | 取当前时间戳(秒) | 本文开头 |
os.tmpname(…) | 生成一个临时文件名 | 本文开头 |
os.difftime
- 作用:两个时间戳之差(秒)
- 调用形态:
os.difftime(…)(库级函数) - 参数:无参数
- 返回:1 个值
- 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机
os.setlocale
- 作用:设置语言区域(影响日期与大小写规则)
- 调用形态:
os.setlocale(…)(库级函数) - 参数:无参数
- 返回:1 个值
- 可用机型:软 PLC 模拟器 / 上位机