Search code examples
node.jsredischild-processredis-cli

node child_process not writing everything to stdout


I'm trying to use node's spawn/exec functions from the child_process module. But I'm noticing a strange difference between what I see in a real terminal and on the command line. Here's an example:

Terminal:

$ redis-cli
127.0.0.1:6379> hmset hash name Jack age 33
OK
127.0.0.1:6379> hscan hash 0
1) "0"
2) 1) "name"
   2) "Jack"
   3) "age"
   4) "33"

In node.js:

const child = exec("redis-cli");
child.stdin.setDefaultEncoding("utf-8");
child.stdout.on("data", data => console.log(data.toString()));

child.stdin.write("hmset hash name Jack age 33\n"); // same as first command from cli example

await new Promise(r => setTimeout(r, 1000));

child.stdin.write("hscan hash 0\n"); // same as second command from cli example

await new Promise(r => setTimeout(r, 1000));

This is what gets written to the console:

OK

0
name
Jack
age
33

In this case the numbers 1), 2) etc. are missing. Any ideas how I can persuade child_process to also write them to the console? I'm guessing that this particular example is a quirk of how redis-cli is implemented, but the data must be going somewhere.

the await new Promise(...) calls are just to ensure that the previous command is finished for this simple example.


Solution

  • As is often the case, I figured this out within one minute of posting the question.

    redis-cli tries to detect if the standard output is a terminal. This problem is solved by using

    const child = exec("redis-cli --no-raw");
    

    instead of

    const child = exec("redis-cli");
    

    RTFM.