Redis允许您通过它的SCRIPT LOAD命令上传Lua脚本,其文件说返回的"SHA-1散列“可以通过EVALSHA调用。这一切都如预期的那样有效。
然后我对部署过程的一部分进行了“优化”,这样我们就有了一个单独的程序来上传Lua脚本。它使用Unix sha1sum命令生成SHA-1散列,因为我(天真地)假定Redis实际上使用了给定的文件的SHA-1。但是在这样做之后,当我试图在Redis中使用NOSCRIPT脚本时,我一直得到EVAL错误。
显然是Redis (我使用的是v3.0.6)在生成SHA-1哈希之前会修改脚本(下面是演示)。
我将讨论到最简单的测试用例,从下面的脚本开始:
test.lua:
return nil我确保脚本文件是我所认为的那样,并且shell (Bash)没有对它做任何奇怪的事情:
$ hexdump -C test.lua
00000000 72 65 74 75 72 6e 20 6e 69 6c 0a |return nil.|
0000000b
$ sha1sum test.lua
6f65c1b09395aee959e644fa26d4c6ca6f0d462d test.lua
$ echo "$(cat test.lua)" | sha1sum
6f65c1b09395aee959e644fa26d4c6ca6f0d462d -当然,我将SHA-1哈希与SHA-1的在线JavaScript实现进行了比较:
6F65C1B09395AEE959E644FA26D4C6CA6F0D462D然后我把它装进Redis:
$ redis-cli SCRIPT LOAD "$(cat test.lua)"
"79cefb99366d8809d2e903c5f36f50c2b731913f"为了猜测Redis可能对脚本做了什么,我也尝试了使用Windows样式的CRLF,而不是Unix样式的LF行提要,但这也不符合Redis的结果:
$ hexdump -C test.lua
00000000 72 65 74 75 72 6e 20 6e 69 6c 0d 0a |return nil..|
0000000c
$ sha1sum test.lua
98260fd830c34607e437f5e418683c2a644b0d82 test.lua最后,恼怒的是,我试着删除所有的空格,瞧!结果是一致的。
在进一步修改后,我发现由于某种原因,--最后一行中的尾随空格字符--似乎被Redis删除了!
作为证据,下面的示例适用于LF或CRLF,但如果将LF或CRLF添加到最后一行,则失败:
$ hexdump -C test.lua
00000000 69 66 20 74 72 75 65 20 74 68 65 6e 0a 72 65 74 |if true then.ret|
00000010 75 72 6e 20 6e 69 6c 0a 65 6e 64 |urn nil.end|
0000001b
$ sha1sum test.lua
ee9d1de0dae159d76a57ecb8e7e8c8c75283ef1d test.lua
$ redis-cli SCRIPT LOAD "$(cat test.lua)"
ee9d1de0dae159d76a57ecb8e7e8c8c75283ef1d,那么是什么呢?为什么Redis要在计算该文件的散列之前对脚本文件的最后一行进行变异?
"$(...)"上传脚本,即使是StackOverflow推荐这个表单。redis-cli -x SCRIPT LOAD < script.lua,它通过stdin将文件导入redis-cli,避免了变异。标志告诉redis-cli读取来自stdin的下一个参数。发布于 2018-05-10 21:45:09
我不知道,但幸运的是,有一个解决方案给这里
CHECKSUM=$(redis-cli -x script load < test.lua)这样做的好处是,如果算法将来发生变化,您仍然会得到一个“正确”的校验和。
https://stackoverflow.com/questions/50281789
复制相似问题