了解 Nginx+OpenResty 中内联 Lua 代码中字符串的引用
Understanding quoting of strings in inline Lua code in Nginx+OpenResty
为了测试,我需要使用 OpenResty 在 Nginx 服务器中创建一些假数据。我需要创建一个复制一个 IP 地址的数组,例如:
["1.2.3.4", "1.2.3.4", ...]
在 Ruby 中,实现可能如下所示:
"[" + (["\"1.2.3.4\""] * 4096).join(", ") + "]"
我是 Lua 的初学者,为了让它在 OpenResty 环境中工作,我付出了很多努力。这似乎终于奏效了:
content_by_lua '
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = "\"1.2.3.4\"" end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
'
我在字符串引用方面遇到了一些问题。首先,我尝试了 '"1.2.3.4"'
,它在内联 Lua 部分不起作用。这是可以理解的,因为 '
字符已经是 content_by_lua
部分的分隔符。
接下来,我尝试了 "\"1.2.3.4\""
,我希望它能工作,但它导致了这个(令人困惑的)错误:
failed to load inlined Lua code:
content_by_lua(nginx.conf:235):17: malformed number near '1.2.3.4'
通过反复试验,我发现如果使用双引号 ("\"1.2.3.4\""
),此错误就会消失。这在 OpenResty 中有效,尽管如果我在 Lua REPL:
中尝试相同的代码会被拒绝
$ rep.lua
Lua REPL 0.8
> "\"1.2.3.4\""
[string "REPL"]:1: unexpected symbol near '"\"'
为了帮助我理解并成为更好的Lua/OpenResty程序员,我对引用有一些疑问:
- 为什么需要双引号(在 OpenResty 中)? (为什么
"\"1.2.3.4\""
而不是 "\"1.2.3.4\""
?)
- 为什么 OpenResty 的行为与 Lua REPL 不同?
- 是否可以在
content_by_lua
部分中使用单引号? (简化为'"1.2.3.4"'
)
(另外,一个无关的问题困扰着我。有没有更简单的代码表达方式?当我将它与我的 Ruby 片段进行比较时,我很确定它也可以表达在 Lua 中更优雅。)
正如 Egor 所说,这是因为反斜杠字符 \
在被 Lua 解析之前被 nginx 配置文件解析器删除。在您的情况下,"\"1.2.3.4\""
是正确的,因为它被 nginx 配置解析器解析为 "\"1.2.3.4\""
,然后被 Lua.
解析为字符串 "1.2.3.4"
如果您不想担心要使用多少个反斜杠,有两种选择。最简单的是使用 content_by_lua_block
,从 OpenResty v0.9.17 开始可用。
content_by_lua_block {
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = '"1.2.3.4"' end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
}
如果您不能在您的 OpenResty 版本中使用 Lua 块,您可以使用 Lua 的 multiline string syntax.
content_by_lua '
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = [["1.2.3.4"]] end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
'
有关详细信息,请参阅 OpenResty docs。
此外,如果您想完全避免使用表格,您可以使用 string.rep
.
制作相同的测试数据
content_by_lua '
-- ... some code ...
local ip = [["1.2.3.4"]]
local fakeResponse = "[" .. string.rep(ip .. ", ", 4095) .. ip .. "]"
--- ...
'
为了测试,我需要使用 OpenResty 在 Nginx 服务器中创建一些假数据。我需要创建一个复制一个 IP 地址的数组,例如:
["1.2.3.4", "1.2.3.4", ...]
在 Ruby 中,实现可能如下所示:
"[" + (["\"1.2.3.4\""] * 4096).join(", ") + "]"
我是 Lua 的初学者,为了让它在 OpenResty 环境中工作,我付出了很多努力。这似乎终于奏效了:
content_by_lua '
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = "\"1.2.3.4\"" end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
'
我在字符串引用方面遇到了一些问题。首先,我尝试了 '"1.2.3.4"'
,它在内联 Lua 部分不起作用。这是可以理解的,因为 '
字符已经是 content_by_lua
部分的分隔符。
接下来,我尝试了 "\"1.2.3.4\""
,我希望它能工作,但它导致了这个(令人困惑的)错误:
failed to load inlined Lua code:
content_by_lua(nginx.conf:235):17: malformed number near '1.2.3.4'
通过反复试验,我发现如果使用双引号 ("\"1.2.3.4\""
),此错误就会消失。这在 OpenResty 中有效,尽管如果我在 Lua REPL:
$ rep.lua
Lua REPL 0.8
> "\"1.2.3.4\""
[string "REPL"]:1: unexpected symbol near '"\"'
为了帮助我理解并成为更好的Lua/OpenResty程序员,我对引用有一些疑问:
- 为什么需要双引号(在 OpenResty 中)? (为什么
"\"1.2.3.4\""
而不是"\"1.2.3.4\""
?) - 为什么 OpenResty 的行为与 Lua REPL 不同?
- 是否可以在
content_by_lua
部分中使用单引号? (简化为'"1.2.3.4"'
)
(另外,一个无关的问题困扰着我。有没有更简单的代码表达方式?当我将它与我的 Ruby 片段进行比较时,我很确定它也可以表达在 Lua 中更优雅。)
正如 Egor 所说,这是因为反斜杠字符 \
在被 Lua 解析之前被 nginx 配置文件解析器删除。在您的情况下,"\"1.2.3.4\""
是正确的,因为它被 nginx 配置解析器解析为 "\"1.2.3.4\""
,然后被 Lua.
"1.2.3.4"
如果您不想担心要使用多少个反斜杠,有两种选择。最简单的是使用 content_by_lua_block
,从 OpenResty v0.9.17 开始可用。
content_by_lua_block {
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = '"1.2.3.4"' end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
}
如果您不能在您的 OpenResty 版本中使用 Lua 块,您可以使用 Lua 的 multiline string syntax.
content_by_lua '
-- ... some code ...
local ips = {}
for i=1,4096 do ips[i] = [["1.2.3.4"]] end
local fakeData = table.concat(ips, ", ")
local fakeResponse = "[" .. fakeData .. "]"
--- ...
'
有关详细信息,请参阅 OpenResty docs。
此外,如果您想完全避免使用表格,您可以使用 string.rep
.
content_by_lua '
-- ... some code ...
local ip = [["1.2.3.4"]]
local fakeResponse = "[" .. string.rep(ip .. ", ", 4095) .. ip .. "]"
--- ...
'