首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在计算脚本的SHA1散列之前,Redis要修剪后面的空格?

为什么在计算脚本的SHA1散列之前,Redis要修剪后面的空格?
EN

Stack Overflow用户
提问于 2018-05-10 21:29:54
回答 1查看 333关注 0票数 2

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:

代码语言:javascript
复制
return nil

我确保脚本文件是我所认为的那样,并且shell (Bash)没有对它做任何奇怪的事情:

代码语言:javascript
复制
$ 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实现进行了比较:

代码语言:javascript
复制
6F65C1B09395AEE959E644FA26D4C6CA6F0D462D

然后我把它装进Redis:

代码语言:javascript
复制
$ redis-cli SCRIPT LOAD "$(cat test.lua)"
"79cefb99366d8809d2e903c5f36f50c2b731913f"

为了猜测Redis可能对脚本做了什么,我也尝试了使用Windows样式的CRLF,而不是Unix样式的LF行提要,但这也不符合Redis的结果:

代码语言:javascript
复制
$ 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添加到最后一行,则失败:

代码语言:javascript
复制
$ 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要在计算该文件的散列之前对脚本文件的最后一行进行变异?

编辑:解决方案,由 mwp 伊塔玛·哈伯和a 提供

  1. 显然,这在本质上是一个Bash问题,可能与壳变量有关,尽管似乎只有尾随换行线受到影响。
  2. 不要使用"$(...)"上传脚本,即使是StackOverflow推荐这个表单
  3. 使用redis-cli -x SCRIPT LOAD < script.lua,它通过stdin将文件导入redis-cli,避免了变异。标志告诉redis-cli读取来自stdin的下一个参数。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-10 21:45:09

我不知道,但幸运的是,有一个解决方案给这里

代码语言:javascript
复制
CHECKSUM=$(redis-cli -x script load < test.lua)

这样做的好处是,如果算法将来发生变化,您仍然会得到一个“正确”的校验和。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50281789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档