Lua - popen命令有多个双引号

时间:2014-12-06 16:30:50

标签: lua

我正在编写一个Lua脚本来管理Windows上的Virtualbox。

似乎没有正确解析多个双引号。我正在使用以下函数来实现这个:

--Get output from an OS command - http://stackoverflow.com/questions/132397/get-back-the-output-of-os-execute-in-lua
function os.capture(cmd, raw)
  local f = assert(io.popen(cmd, 'r'))
  local s = assert(f:read('*a'))
  f:close()
  if raw then return s end
  s = string.gsub(s, '^%s+', '')
  s = string.gsub(s, '%s+$', '')
  s = string.gsub(s, '[\n\r]+', ' ')
  return s
end

这段代码的工作时间很长,机器名称没有空格,但机器可以有空格,所以我必须支持它们:

local command = '"\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo '..key

以下代码根本不起作用,但它确实为日志文件提供了正确的命令格式,因此语法应该是正确的:

local command = '"\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo "'..key..'"'
logger:write("[",os.date("%Y-%m-%d %H:%M:%S"),"] Command: ",command,"\n") 
vmStateRaw = os.capture(command, "raw")

Log file entry:
[2014-12-06 16:09:18] Command: "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"

Interpreter output:
'\Program' is not recognized as an internal or external command,
operable program or batch file.

我发现以下语法有效:

        local command = '""\\Program Files\\Oracle\\VirtualBox\\VBoxManage\" showvminfo "'..key..'"'

Log file output:
[2014-12-06 16:27:54] Command: ""\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"

所以这个问题并不能解决问题,因为我已经做到了。我想理解为什么最后一个命令有效,因为我当前的理解意味着这不起作用。

TIA

1 个答案:

答案 0 :(得分:2)

问题与C中system的工作方式有关。在Windows下,system内部调用

  

cmd / c 您的输入

由于os.execute只委托给systemsee here),您的命令很可能最终执行为:

cmd /c "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"

供参考,来自help cmd

  

如果指定了/ C或/ K,那么后面的命令行的其余部分   交换机作为命令行处理,其中包含以下逻辑   用于处理引号(“)字符:

     
      
  1. 如果满足以下所有条件,则引用字符      在命令行上保留:

         
        
    • 否/ S开关
    •   
    • 正好两个引号字符
    •   
    • 两个引号字符之间没有特殊字符,    special是以下之一:&<>()@ ^ |
    •   
    • 之间有一个或多个空格字符    两个引号字符
    •   
    • 两个引号字符之间的字符串是名称    可执行文件。
    •   
  2.   
  3. 否则,旧行为是查看第一个字符是否为      引用字符,如果是这样,剥去主角和      删除命令行上的最后一个引号字符,保留      最后一个引号字符后面的任何文字。

  4.   

由于您的命令中包含4个双引号,因此它会使用旧行为解析您的命令。这就是为什么你需要用一组额外的"双引号括起你的整个命令。