在 Lua 中获取当前工作目录

22

如何在Windows XP SP3上获取当前工作目录的Lua代码(或获取当前运行的Lua文件的目录)? 我不想使用LuaFileSystem

我不能使用os.execute("cd"),因为os.execute始终从我的主目录开始(因此始终产生C:\Documents and Settings\username)。

6个回答

21

也许像某些丑陋的黑客一样

current_dir=io.popen"cd":read'*l'

这似乎具有与 os.execute("cd") 相同的效果。 - user600838
3
不对,os.execute'cd' 只会输出结果,而 io.popen 则可以捕获输出并将其放入 current_dir 变量中。 - jpjacobs
必须关闭“popen” - 可能将popen存储在本地并在读取后关闭它。否则,这将泄漏句柄。 - Arun R
1
@ArunR 它只会在垃圾回收时短暂地“泄漏”句柄。尝试 print(io.popen("ls").__gc) - Craig Barnes
在我的 macOS 上使用 Lua 5.4,它对我无效,返回 nil - jdhao

13

Lua默认情况下没有支持“当前目录”或“目录”概念的“本地”方式。

获取当前目录的正确方法是使用提供文件夹支持的库。 有几个库可供选择 - 我建议使用luafilesystem

安装后,您可以通过执行以下操作来获取当前目录:

lfs.currentdir()

这将适用于Windows、Linux和Mac。

但请注意,这些外部库通常涉及一些二进制包。根据您的设置,您可能需要在使用之前进行编译。

编辑:

请注意,当文件通过require被包含时,表达式{...}[1]返回require指令使用的路径。它不是完整路径,因为:

  • 它使用点来分隔目录并省略文件结尾处的.lua扩展名。
  • 它相对于初始化lua进程的路径。
  • 它取决于package.path的配置。

但是如果你只需要文件的“require-like路径”(也许是为了要求旁边的文件),那么你可以在文件开始时执行以下操作:

local PATH = (...):match("(.+)%.[^%.]+$") or (...)
如果使用require 'foo.bar.baz'来引入名为baz.lua的文件,则PATH将是foo.bar

谢谢。看起来我只能使用LuaFS了。 - user600838

9

你可以通过以下方式获取当前运行的lua文件路径:

debug.getinfo(1).short_src;

或者

debug.getinfo(1).source;

然后使用正则表达式匹配当前目录:

string.gsub(debug.getinfo(1).short_src, "^(.+\\)[^\\]+$", "%1");

编辑:实际上,仅在使用完整路径运行Lua时才起作用。 例如:“lua.exe C:\test\test.lua”,而不是“lua.exe test.lua”。


3
在Linux中,我必须使用debug.getinfo(1).source并将正则表达式更改为string.gsub(debug.getinfo(1).source, "^@(.+/)[^/]+$", "%1") - Gus E
对于一个玩弄neovim配置文件的lua新手来说,你的回答真是太好了!谢谢 @GusE - Gru

6

我还没有时间测试,但你是否尝试过使用os.getenv读取Windows环境变量?

Windows有一个当前目录的环境变量:%CD%

os.getenv("CD")

编辑: 在Windows 7上进行了测试,虽然其他环境变量有效(例如%USERNAME%或%PROGRAMFILES%),但CD变量返回nil。


是的,我尝试过getenv,但没有成功。我开始觉得如果没有LuaFileSystem可能不可能实现。 - user600838
我能够将%CD%变量传递给脚本,这取决于您如何执行脚本。例如:C:>lua5.1.exe test.lua %CD% (然后路径可用作arg[1])。 - Adam
3
%CD% 不是进程环境变量,它是由Shell提供的,因此它无法工作。 - CharlesB
1
try os.getenv("PWD") on mac - Robert Ranjan

2

我尝试了所有这些答案,但都没有起作用。我测试了以下脚本,它按预期工作。

io.popen("cd"):read()

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接