七、独立版 Lua

虽然 Lua 被设计成一门扩展式语言,用于嵌入一个宿主程序。但经常也会被当成独立语言使用。独立版的 Lua 语言解释器随标准包发布,就叫 lua。独立版解释器保留了所有的标准库及调试库。其命令行用法为:

  1. lua [options] [script [args]]

选项有:

  • -e stat: 执行一段字符串 stat
  • -l mod: “请求模块” mod
  • -i: 在运行完 脚本 后进入交互模式;
  • -v: 打印版本信息;
  • -E: 忽略环境变量;
  • : 中止对后面选项的处理;
  • -: stdin 当作一个文件运行,并中止对后面选项的处理。 在处理完选项后,lua 运行指定的 脚本。如果不带参数调用,在标准输入(stdin)是终端时,lua 的行为和 lua -v -i 相同。否则相当于 lua -

如果调用时不带选项 -E,解释器会在运行任何参数前,检查环境变量 LUA_INIT_5_3(或在版本名未定义时,检查 LUA_INIT )。如果该变量内存格式为 @filenamelua 执行该文件。否则,lua 执行该字符串。

如果调用时有选项 -E,除了忽略LUA_INIT 外,Lua 还忽略 LUA_PATHLUA_CPATH 的值。将 package.pathpackage.cpath 的值设为定义在 luaconf.h 中的默认路径。

-i-E 外所有的选项都按次序处理。例如,这样调用

  1. lua -e'a=1' -e 'print(a)' script.lua

将先把 a 设为 1,然后打印 a 的值,最后运行文件 script.lua 并不带参数。(这里的 $ 是命令行提示。你的命令行提示可能不一样。)

在运行任何代码前,lua 会将所有命令行传入的参数放到一张全局表 arg 中。脚本的名字放在索引 0 的地方,脚本名后紧跟的第一个参数在索引 1 处,依次类推。在脚本名前面的任何参数(即解释器的名字以及各选项)放在负索引处。例如,调用

  1. $ lua -la b.lua t1 t2

这张表是这样的:

  1. arg = { [-2] = "lua", [-1] = "-la",
  2. [0] = "b.lua",
  3. [1] = "t1", [2] = "t2" }

如果调用中没提供脚本名,解释器的名字就放在索引 0 处,后面接着其它参数。例如,调用

  1. $ lua -e "print(arg[1])"

将打印出 "-e" 。如果提供了脚本名,就以 arg[1], ···, arg[#arg]为参数调用脚本。(和 Lua 所有的代码块一样,脚本被编译成一个可变参数函数。)

在交互模式下,Lua 不断的显示提示符,并等待下一行输入。一旦读到一行,首先试着把这行解释为一个表达式。如果成功解释,就打印表达式的值。否则,将这行解释为语句。如果你写了一行未完成的语句,解释器会用一个不同的提示符来等待你写完。

当脚本中出现了未保护的错误,解释器向标准错误流报告错误。如果错误对象并非一个字符串,但是却有元方法__tostring 的话,解释器会调用这个元方法生成最终的消息。否则,解释器将错误对象转换为一个字符串,并把栈回溯信息加在前面。

如果正常结束运行,解释器会关闭主 Lua 状态机(参见 lua_close。脚本可以通过调用os.exit来结束,以回避这个步骤。

为了让 Lua 可以用于 Unix 系统的脚本解释器。独立版解释器会忽略代码块的以 # 打头的第一行。因此,Lua 脚本可以通过chmod +x 以及 #! 形式变成一个可执行文件。类似这样

  1. #!/usr/local/bin/lua

(当然,Lua 解释器的位置对于你的机器来说可能不一样。如果 lua 在你的 PATH 中,写成

  1. #!/usr/bin/env lua

更为通用。)