我想知道是否有办法获取当前正在执行的lua脚本文件的路径?
这特别不是当前的工作目录,可能完全不同。我知道luafilesystem会让我获取当前的工作目录,但它似乎无法告诉当前正在执行的脚本文件。
由于
编辑: 我没有从标准命令行解释器运行,我正在通过luabind从C ++二进制文件执行脚本。
答案 0 :(得分:15)
这是一种更优雅的方式:
function script_path()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*/)")
end
print(script_path())
答案 1 :(得分:6)
如果标准命令行解释器正在运行Lua脚本,请尝试arg[0]
。
答案 2 :(得分:3)
正如lhf所说:
~ e$ echo "print(arg[0])" > test.lua
~ e$ lua test.lua
test.lua
~ e$ cd /
/ e$ lua ~/test.lua
/Users/e/test.lua
/ e$
这是使用debug.getinfo机制的相同信息
~ e$ echo "function foo () print(debug.getinfo(1).source) end; foo()" > test.lua
~ e$ lua test.lua
@test.lua
~ e$ cd /
/ e$ lua ~/test.lua
@/Users/e/test.lua
/ e$
可从C API lua_getinfo
获取答案 3 :(得分:3)
获得所需内容的唯一可靠方法是将dofile
替换为您自己的此函数版本。即使debug.getinfo
方法也不起作用,因为它只会返回传递给dofile
的字符串。如果那是一条相对路径,它就不知道它是如何转换为绝对路径的。
重写代码看起来像这样:
local function CreateDoFile()
local orgDoFile = dofile;
return function(filename)
if(filename) then --can be called with nil.
local pathToFile = extractFilePath(filename);
if(isRelativePath(pathToFile)) then
pathToFile = currentDir() .. "/" .. pathToFile;
end
--Store the path in a global, overwriting the previous value.
path = pathToFile;
end
return orgDoFile(filename); --proper tail call.
end
end
dofile = CreateDoFile(); //Override the old.
函数extractFilePath
,isRelativePath
和currentDir
不是Lua函数;你必须自己写。 extractFilePath
函数从文件名中提取路径字符串。 isRelativePath
获取路径并返回给定路径是否为相对路径名。 currentDir
只返回当前目录。此外,您需要在Windows计算机上使用“\”而不是“/”。
此函数将路径存储在名为path
的全局中。您可以将其更改为您喜欢的任何内容。
答案 4 :(得分:2)
我找到的最短形式如下:
debug.getinfo(1).source:match("@?(.*/)")
索引1,2-其他 - 取决于您要查询的调用堆栈中的哪个函数。 1是最后一个叫做函数(你在哪里)。如果你在全球范围内运行,那么可能2更合适(没有自己测试)
答案 5 :(得分:0)
查看Lua调试库,它是标准Lua发行版的一部分。您可以使用debug.getinfo查找当前文件,或调用堆栈上的N帧文件:
http://www.lua.org/manual/5.1/manual.html#5.9
请注意,这可能相当慢,所以如果你担心这些事情,那么你不想在快速路径上做这件事。
答案 6 :(得分:0)
arg[0]:match('.*\\')
如果返回nil,请尝试使用.\*\\\
更改.*/
,arg[0]
更改debug.getinfo(1).short_src
。
但我发现这是获取当前目录的最佳和最短的方式。
您当然可以使用..
运算符附加您要查找的文件。它看起来像这样:
arg[0]:match('.*\\')..'file.lua'
答案 7 :(得分:0)
如果你想要实际路径:
path.dirname(path.abspath(debug.getinfo(1).short_src))
否则将其用于完整文件路径:
path.abspath(debug.getinfo(1).short_src)
答案 8 :(得分:0)
如果您想要包含文件名的真实路径,请使用以下
pathWithFilename=io.popen("cd"):read'*all'
print(pathWithFilename)
在Windows上测试。
<强>解释强>
io.popen
- 将命令发送到命令行,并返回输出。
"cd"
- 当您在cmd
中输入时,您会将当前路径作为输出。
:read'*all'
- 由于io.popen返回类似文件的对象,您可以使用相同类型的命令读取它。这将读取整个输出。
如果有人需要UNC路径:
function GetUNCPath(path,filename)
local DriveLetter=io.popen("cd "..path.." && echo %CD:~0,2%"):read'*l'
local NetPath=io.popen("net use "..DriveLetter):read'*all'
local NetRoot=NetPath:match("[^\n]*[\n]%a*%s*([%a*%p*]*)")
local PathTMP=io.popen("cd "..path.." && cd"):read'*l'
PathTMP=PathTMP:sub(3,-1)
UNCPath=NetRoot..PathTMP.."\\"..filename
return UNCPath
end
答案 9 :(得分:0)
我编写了一个函数getScriptDir
,它使用了一些其他人建议的调试信息,但这个函数每次都会起作用(至少在Windows中)。但事情是有相当多的代码行,因为它使用了我创建的另一个函数string.cut
,它将每个给定模式的字符串分开,并将其放入表中。
function string.cut(s,pattern)
if pattern == nil then pattern = " " end
local cutstring = {}
local i1 = 0
repeat
i2 = nil
local i2 = string.find(s,pattern,i1+1)
if i2 == nil then i2 = string.len(s)+1 end
table.insert(cutstring,string.sub(s,i1+1,i2-1))
i1 = i2
until i2 == string.len(s)+1
return cutstring
end
function getScriptDir(source)
if source == nil then
source = debug.getinfo(1).source
end
local pwd1 = (io.popen("echo %cd%"):read("*l")):gsub("\\","/")
local pwd2 = source:sub(2):gsub("\\","/")
local pwd = ""
if pwd2:sub(2,3) == ":/" then
pwd = pwd2:sub(1,pwd2:find("[^/]*%.lua")-1)
else
local path1 = string.cut(pwd1:sub(4),"/")
local path2 = string.cut(pwd2,"/")
for i = 1,#path2-1 do
if path2[i] == ".." then
table.remove(path1)
else
table.insert(path1,path2[i])
end
end
pwd = pwd1:sub(1,3)
for i = 1,#path1 do
pwd = pwd..path1[i].."/"
end
end
return pwd
end
注意:如果您想在Windows以外的其他操作系统中使用此功能,则必须将第15行中的io.popen("echo %cd%")
更改为任何命令您在操作系统中显示工作目录,例如适用于Linux的io.popen("pwd")
和第18行中的pwd2:sub(2,3) == ":/"
代表操作系统中根目录的任何内容,例如:适用于Linux的pwd2:sub(1,1) == "/"
。
注2:如果您在调用时没有通过source
向函数提供debug.getinfo(1).source
变量,那么它将返回到目录的路径包含此功能的文件。因此,如果您想获取通过dofile
或loadfile
调用的文件的目录,则必须为其提供源代码,如下所示:getScriptDir(debug.getinfo(1).source)
。