Reputation: 7023
I am a beginner to lua scripting. I tried executing the below command in redis client
eval "print('hello world')" 0
and it works fine returning me
hello
(nil)
Firstly i don't understand why does the nil is returned/gets printed always?? is it because of the lua-datatype to redis-datatype inter-conversion which returns nil??
Then i used if constructs and executed the below script
eval "local t = 0; if t == 0 then print('hello'); end" 0 0
the above command prints as expected
hello
(nil)
But when i tried assigning the arguments to the local variable using the below code
eval "local t = ARGV[1]; if t == 0 then print('hello'); end" 0 0
the output is only
(nil)
So can someone explain me how should the assignments of the external arguments to the local variable be carried out??
Upvotes: 3
Views: 3104
Reputation: 10502
The redis eval command does nothing more than split your input into tokens, hence your argument 0
is a string
, and not a number
.
However, the comparison 0 == "0"
is false in Lua, so what you need to do is change to either of those variants:
eval "local t = ARGV[1]; if t == '0' then print('hello'); end" 0 0
eval "local t = ARGV[1]; if tonumber(t) == 0 then print('hello'); end" 0 0
Note: Since is was kind of mentioned by Kamiccolo; note that in Lua's eval you never have access to local
variables from outside of the eval because code is always evaluated in the global context!
Upvotes: 2
Reputation: 8507
According to Redis EVAL documentation, global variable access from chunk
executed using eval()
to global variables is disabled. It's not mentioned, but I suspect that accessing local
ones is even bigger violation and possible leakage. So, You should follow official documentation and use Redis keys
instead. Or, of course, re-using returned valies.
Relevant chunk from eval()
docs:
Global variables protection
Redis scripts are not allowed to create global variables, in order to avoid leaking data into the Lua state. If a script needs to maintain state between calls (a pretty uncommon need) it should use Redis keys instead.
Just realised, that question's body does not match the question's title, so starting again...
Proper eval()
usage (from Redis docs):
The first argument of EVAL is a Lua 5.1 script. The script does not need to define a Lua function (and should not). It is just a Lua program that will run in the context of the Redis server.
The second argument of EVAL is the number of arguments that follows the script (starting from the third argument) that represent Redis key names. This arguments can be accessed by Lua using the KEYS global variable in the form of a one-based array (so KEYS[1], KEYS[2], ...).
All the additional arguments should not represent key names and can be accessed by Lua using the ARGV global variable, very similarly to what happens with keys (so ARGV[1], ARGV[2], ...).
In Your example You're setting number of arguments to 0
, so, nothing gets passed to Your Lua script. Quick fix:
eval "local t = ARGV[1]; if t == 0 then print('hello'); end" 1 0
Not sure about nil
, but that might be just because Your Lua chunk provided does not return anyhing.
Upvotes: 1