检测 Lua 脚本是被导入还是被直接执行
在 Python 中,有一种常见的形式 if __name__ == "__main__":,用于检测文件是被导入还是被直接执行。通常,在这个条件语句中所执行的唯一操作就是 执行某些 "合理、顶层" 函数。这允许相同的文件可用作基本脚本和库模块 (也可以作为交互式用户可以导入和使用的东西)。
我想知道在 Lua 中是否有一种干净和可靠的方法来做到这一点。我认为我可以使用 _REQUIREDNAME 全局变量,但这在 Lua 5.1 中已被更改。目前,Lua 的 require 会传递参数 (在可变参数 ... 中),因此原则上这些参数可以被检查。但是,这要么不可靠,要么不干净,或者两者都是,因为很明显当脚本被执行时可以传递参数。所以要安全地做到这一点,你必须检查这些参数。
顺便说一下,require 会将模块名称作为第一个参数 (你调用 require 的字符串) 并将其找到的文件的路径作为第二个参数传递。因此,可以进行一些检查来尝试检测这一点,不过这并不像 if __name__ == "__main__": 那样好,而且用户总是可以通过传递两个合适构造的参数来绕过它。这并不是一种安全威胁,但我希望有更好的解决方案。
我还尝试了另一种方法,我觉得非常丑陋但很有前途。这是使用 debug.traceback()。如果脚本是被直接执行的,那么返回的跟踪信息非常可预测,实际上只有 3 行。我认为这可能就是解决方案,尽管像我说的那样,这是一种丑陋的破解方法。
有没有更频繁地使用 Lua 的用户可以提供建议呢?事实上,如果我正在编写模块 X,我想在脚本模式下返回 X.main_func() 或者在导入模式下返回 X。
编辑: 我删掉了一个其实是错误的项目 (使我的 traceback 解决方案可行)。此外,Egor Skriptunoff 在评论中提供的链接提供了 debug 库中的另一个技巧,它比使用 traceback 更干净。除此之外,似乎每个人都遇到了与我相同的问题,而且 Lua 团队对提供官方支持此功能并不感兴趣。
在 package.loaded 中返回 require()。
因此,可以简单地检查 package.loaded 来获取所需内容。
此外,作为更多经验的良好起点,建议编写 package.preload 函数以获取 require() 的内容,而无需操作路径。
以下是一个简单的示例...
# /usr/local/bin/lua -i
Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
> package.preload.mymod=function() return {dump=function(...)
>> local args={...}
>> local test,dump=pcall(assert,args[1])
>> if test then
>> for key,value in pairs(dump) do
>> io.write(string.format("%s=%s\n",key,value)):flush()
>> end
>> return true
>> else
>> return test,dump
>> end
>> end} end
> mymod=require('mymod')
> mymod.dump(package.loaded)
string=table: 0x56693590
mymod=table: 0x566aa890
utf8=table: 0x56694d80
package=table: 0x56691ed0
math=table: 0x56693cb0
table=table: 0x566920d0
_G=table: 0x56690730
debug=table: 0x566950e0
coroutine=table: 0x56692310
os=table: 0x56692e60
io=table: 0x566921b0
true
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

根据 Egor 提供的链接,目前最清洁和安全的做法似乎是以下示例:
如何确定我的代码是否在 Lua 模块中运行?
我在此重复一下以供参考:
if pcall(debug.getlocal, 4, 1) then print("in package") else print("in main script") end有一个完整的线程在这里讨论:
http://lua.2524044.n2.nabble.com/Modules-with-standalone-main-program-td7681497.html
就像我说的那样,似乎这是一个普遍的功能,暂时不受支持,但 debug.getlocal 方法似乎是普通 Lua 开发人员现在所采用的方法。