我正在编写一个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
答案 0 :(得分:2)
问题与C中system
的工作方式有关。在Windows下,system
内部调用
cmd / c 您的输入
由于os.execute
只委托给system
(see here),您的命令很可能最终执行为:
cmd /c "\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo "Cerium"
供参考,来自help cmd
:
如果指定了/ C或/ K,那么后面的命令行的其余部分 交换机作为命令行处理,其中包含以下逻辑 用于处理引号(“)字符:
如果满足以下所有条件,则引用字符 在命令行上保留:
- 否/ S开关
- 正好两个引号字符
- 两个引号字符之间没有特殊字符, special是以下之一:&<>()@ ^ |
- 之间有一个或多个空格字符 两个引号字符
- 两个引号字符之间的字符串是名称 可执行文件。
- 醇>
否则,旧行为是查看第一个字符是否为 引用字符,如果是这样,剥去主角和 删除命令行上的最后一个引号字符,保留 最后一个引号字符后面的任何文字。
由于您的命令中包含4个双引号,因此它会使用旧行为解析您的命令。这就是为什么你需要用一组额外的"
双引号括起你的整个命令。