在读取 Lua 模块文件时尝试获取 PATH 变量的值。

我正在尝试在 lua 脚本中读取模块文件中给定的 PATH 变量的值。我不确定是否可以使用 lua 中的某些函数来完成这项任务,因为我对 lua 还比较陌生。

模块文件(netcdf),下面只给出了部分模块文件 -

set application netcdf
set version 4.1.1

set machine kgb
set app_base /sw/$machine/$application/$version

module-whatis "Sets up environment to use serial netcdf"
if [ module-info mode whatis ] {
  break
}

  #vvvvv If if not a library, remove this part vvvvv
  if [ is-loaded intel ] {
    set app_build "centos6.2_intel12"
  } elseif [ is-loaded gcc ] {
    set app_build "centos6.2_gnu4.4.6"
    break
  } elseif [ is-loaded pgi ] {
    set app_build "centos6.2_pgi12.3"
    break
  } else {
    puts stderr "You must have a programming environment loaded to use this module"
    break
  }
  #^^^^^ If if not a library, remove this part ^^^^^

  # This assumes something like --prefix=$SW_BLDDIR
  set app_path $app_base/$app_build

  setenv NETCDF_DIR "$app_path"
  setenv NETCDF_INCLUDE "$app_path/include"
  setenv NETCDF_LIB "$app_path/lib"
  #setenv NETCDF_LINK "-I${FOO_INCLUDE} -L${FOO_LIB} -lfoo"

  prepend-path PATH             "$app_path/bin"
  prepend-path LD_LIBRARY_PATH  "$app_path/lib"

我正在读取此文件,是否有任何方法可以获取所有三个可能的 PATH 组合值,而不考虑用户/系统的环境,即:

- PATH = /sw/kgb/netcdf/4.1.1/centos6.2_intel12/bin
- PATH = /sw/kgb/netcdf/4.1.1/centos6.2_gnu4.4.6/bin
- PATH = /sw/kgb/netcdf/4.1.1/centos6.2_pgi12.3/bin

我编写的代码只读取了文件的每一行,但是很难将值排列到变量中并获取所需的 PATH。

Lua 代码 -

-- reading module file
local mfile = v.file
local lines = lines_from(mfile)

-- print all line numbers and their contents
for k ,v in pairs(lines)do
   print('line['..k..']',v)
end

-- see if file exists
function file_exists(file)
   local f = io.open(file,"rb")
   if f then f:close() end
   return f~= nil
end

-- get all lines from a file, returns an empty
-- list/table if the file does not exists
function lines_from(file)
   if not file_exists(file) then return {} end
   local lines = {}
   for line in io.lines(file) do
     if (string.match(line, 'set') or string.match(line,'prepend'))then
       lines[#lines+1] = line
     end
   end
   return lines
end

我获得的输出只显示了我需要的感兴趣的行,但是获得所有可能的 PATH 值仍然离我很远,谢谢您的帮助!

点赞
用户869951
用户869951

Really depends how much you know about the non-Lua file:

  1. 在一个极端情况下,文件永远不会发生改变,除了变量的实际值(所以所有的分支、设置和 setenvs 都保持在相同的位置同样的顺序,只有字符串文字改变);
  2. 在另一个极端情况下,文件可以完全改变,只是文件的某个位置设置了 PATH。

对于 #1 情况,你可以很容易地使用 Lua 的模式匹配功能找到所有关于 app_build 的设置,并从中确定 PATH 的 3 个值(无需解析其他变量,因为结构不会改变,可以在 Lua 代码逻辑中加以考虑)。

对于 #2 情况,你有两个选项:

  1. 你可以为脚本语言(bash?)建立一个解析器:你可以使用 Lua 的 LPEG 库,但这是一项相当困难的事情,不太可能实现。
  2. 你可以使用 Lua 将 bash 文件复制到一个新文件中,但添加一些 bash 命令将 PATH 输出到 stdout,然后你使用 io.popen 运行临时脚本使用 bash 并捕获其输出。然后,你可以使用 Lua 的模式匹配功能来查找 PATH 的值。你的 Lua 脚本将对此进行 io.popen 3 次,每次处理 3 个选项中的一个。根据脚本中的注释,脚本只能在编程环境内运行,因此这种方法可能不太可行。

所以实际上,对于 #2 情况,你很可能会失败,对于 #1 情况,你走在正确的道路上。如果后者是你的情况,但你在获取所有变量时遇到问题,请在评论中进行提问,我将在我的答案中加入一个示例。

2014-07-04 01:27:43