Lua - 使用多个双引号打开命令

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

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

- 来自 OS 命令的输出 - 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")

日志文件条目:
[2014-12-06 16:09:18] Command: "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"

解释器输出:
'\Program' 不是内部或外部命令,可操作的程序或批处理文件。

我发现以下语法有效:

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

日志文件输出:
[2014-12-06 16:27:54] Command: ""\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"

所以,这个问题不是为了解决问题,因为我已经解决了这个问题。我想了解为什么最后一条命令起作用,因为我的当前理解意味着这应该不起作用。

TIA

点赞
用户234175
用户234175

这个问题与 C 语言中的 system 函数有关。在 Windows 中,system 内部调用

cmd /c yourinput

由于 os.execute 仅是委托给 system (在这里查看),所以你的命令最终会执行为:

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

参考自 help cmd

如果指定了/C或/K,则在开关之后的命令行的其余部分将作为命令行处理,其中使用以下逻辑处理引号 (") 字符:

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

    • 没有 /S 开关
    • 正好有两个引号字符
    • 在两个引号字符之间没有特殊字符,其中“特殊字符”是 &<>()@^|
    • 在两个引号字符之间有一个或多个空白字符
    • 两个引号字符之间的字符串是可执行文件的名称。
  2. 否则,旧行为是查看第一个字符是否是引号字符,如果是,则删除前导字符,并删除命令行上最后一个引号字符,保存最后一个引号字符后的任何文本。

由于你的命令中有 4 个双引号,它使用旧行为解析你的命令。这就是为什么你需要在整个命令外面再加一组双引号的原因。

2014-12-06 21:57:59