LuaFileSystem(LFS)库导入报错问题求助
我编写了一段Lua代码,用于检查指定目录下的文件夹,将超过2天的文件夹归档以提升服务器性能。我通过luarocks install luafilesystem安装了LFS库,但加载库时出现报错:
E0728 12:51:42.507733 MAIN OrthancException.cpp:61] Cannot execute a Lua command: error loading module 'lfs' from file '/usr/local/lib/lua/5.1/lfs.so':
/usr/local/lib/lua/5.1/lfs.so: undefined symbol: lua_gettop
E0728 12:51:42.508185 MAIN ServerIndex.cpp:348] INTERNAL ERROR: ServerIndex::Stop() should be invoked manually to avoid mess in the destruction order!
我尝试添加代码指定LFS路径到package.cpath,但问题仍未解决:
local lfs_path = "/usr/local/lib/lua/5.1/lfs.so" -- 更新为lfs.so的实际路径 -- 将路径添加到package.cpath package.cpath = package.cpath .. ";" .. lfs_path
我的完整Lua代码如下:
-- 定义LuaFileSystem库的路径 local lfs_path = "/usr/local/lib/lua/5.1/lfs.so" -- 更新为lfs.so的实际路径 -- 将路径添加到package.cpath package.cpath = package.cpath .. ";" .. lfs_path -- 加载LuaFileSystem库 local lfs = require("lfs") local function isOlderThanTwoDays(path) local attr = lfs.attributes(path) if attr and attr.mode == "directory" then local age = os.difftime(os.time(), attr.modification) return age > 2 * 24 * 60 * 60 end return false end local function archiveFolder(path) local archiveName = path .. ".tar.gz" os.execute(string.format("tar -czf %s %s", archiveName, path)) os.execute(string.format("rm -rf %s", path)) end local function checkAndArchiveFolders(dirs) for _, dir in ipairs(dirs) do for file in lfs.dir(dir) do if file ~= "." and file ~= ".." then local fullPath = dir .. "/" .. file if isOlderThanTwoDays(fullPath) then archiveFolder(fullPath) end end end end end -- 使用示例 local directoriesToCheck = { "/etc/orthanc/ClientRpts/IVH" -- "/path/to/your/second_directory", -- 按需添加更多目录 }
核心问题原因
报错undefined symbol: lua_gettop是因为你安装的LFS库与Orthanc内嵌的Lua版本不兼容:LFS是针对系统标准Lua5.1编译的,但Orthanc使用的是定制或静态编译的Lua,导致符号匹配失败。
修复步骤
方法一:针对Orthanc的Lua环境重新编译LFS
- 获取Orthanc使用的Lua源码版本(通常与Orthanc源码绑定),或使用Orthanc提供的编译环境
- 下载LuaFileSystem源码并重新编译:
wget https://github.com/keplerproject/luafilesystem/archive/refs/tags/v1.8.0.tar.gz tar xzf v1.8.0.tar.gz cd luafilesystem-1.8.0 # 修改Makefile,指定Orthanc的Lua头文件路径和库文件 # 例如:LUA_INC = /path/to/orthanc/lua/include # LUA_LIB = /path/to/orthanc/lua/lib/liblua.a make # 将编译好的lfs.so复制到Orthanc可加载的路径,比如Orthanc的Lua模块目录 cp src/lfs.so /usr/share/orthanc/lua/
方法二:不使用LFS,改用系统命令实现功能
既然代码中已用到os.execute,可以直接通过shell命令替代LFS的目录遍历和属性获取逻辑,彻底规避兼容性问题:
local function checkAndArchiveFolders(dirs) for _, dir in ipairs(dirs) do -- 用find命令找出2天前的目录(排除当前目录和上级目录) local cmd = string.format("find %s -maxdepth 1 -type d -mtime +2 ! -path %s ! -path %s/..", dir, dir, dir) local handle = io.popen(cmd) if handle then for line in handle:lines() do local archiveName = line .. ".tar.gz" -- 归档并删除原目录 os.execute(string.format("tar -czf %s %s", archiveName, line)) os.execute(string.format("rm -rf %s", line)) end handle:close() end end end -- 使用示例 local directoriesToCheck = { "/etc/orthanc/ClientRpts/IVH" -- "/path/to/your/second_directory", -- 按需添加更多目录 } -- 执行检查归档 checkAndArchiveFolders(directoriesToCheck)
方法三:确认Orthanc的Lua模块加载路径
如果坚持使用LFS,先在代码开头添加以下代码打印package.cpath的实际路径:
print("Current package.cpath: " .. package.cpath)
然后将编译好的兼容版本LFS放到输出的路径中,而非硬编码系统Lua的路径。
内容的提问来源于stack exchange,提问作者Zeyad Khaled

