Я написал функцию 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, вы должны изменить io.popen("echo %cd%")
в строке 15 на любую команду, которая предоставляет вам текущий рабочий каталог в вашей ОС,например, io.popen("pwd")
для Linux и pwd2:sub(2,3) == ":/"
в строке 18 для любого корневого каталога в вашей ОС, например, pwd2:sub(1,1) == "/"
для Linux.
Примечание2: если вы не передадите в функцию переменную source
через debug.getinfo(1).source
при вызове, она вернет путь к каталогу файла , содержащего эту функцию .Поэтому, если вы хотите получить каталог файла, который вы вызывали с помощью dofile
или loadfile
, вам нужно будет указать ему источник, например: getScriptDir(debug.getinfo(1).source)
.