gpt4 book ai didi

redis - 为什么 Redis 在计算脚本的 SHA1 哈希之前要修剪尾随空格?

转载 作者:IT王子 更新时间:2023-10-29 06:06:09 33 4
gpt4 key购买 nike

Redis 允许您通过其 SCRIPT LOAD 上传 Lua 脚本命令,和 its documentation表示可以通过 EVALSHA 调用返回的“SHA-1 哈希” .正如预期的那样有效。

然后我“优化”了部署过程的一部分,这样我们就有了一个单独的程序来上传 Lua 脚本。它使用 Unix sha1sum 生成 SHA-1 哈希命令,因为我(天真地)假设 Redis 实际上使用了给定文件的 SHA-1。但是在这样做之后,我一直得到 NOSCRIPT尝试 EVAL 时出错Redis 中的脚本。

显然,Redis(我使用的是 v3.0.6)在生成 SHA-1 哈希之前改变了脚本(下面的演示)。


归结为最简单的测试用例,我从这个脚本开始:

测试.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 在计算文件的哈希值之前改变脚本文件的最后一行?


编辑:解决方案,由 mwp 提供, Itamar Haber , 和一个 GitHub issue :

  1. 这显然是 Bash 的核心问题,可能与 mysterious IFS shell variable 有关,即使似乎只有尾随换行符受到影响。

  2. 不要使用 "$(...)"上传脚本,即使StackOverflow recommends that form .

  3. 使用 redis-cli -x SCRIPT LOAD < script.lua ,它通过管道传输文件 stdinredis-cli , 避免突变。 -x flag告诉redis-clistdin 中读取下一个参数.

最佳答案

我不知道,但幸运的是给出了一个解决方案 here :

CHECKSUM=$(redis-cli -x script load < test.lua)

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

关于redis - 为什么 Redis 在计算脚本的 SHA1 哈希之前要修剪尾随空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50281789/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com