Sample Header Ad - 728x90

How to compare output of a program with a reference value in a shell script?

0 votes
1 answer
155 views
I have my own implementation of a Redis server which I'd like to test through a shell script. The general idea is to feed it with some commands through nc, and since nc prints the output of my program (response) to stdout, to capture the response in a script variable and compare it with the expected output. I haven't been able to get it to work and I don't know what the issue is and how to solve it. This is a part of the script:
#!/bin/bash

set -eu

PORT=6380;

RUST_LOG=info ./run.sh --port $PORT 2>/dev/null & sleep 1; # Give it some time to start.

i=0;

i=$((i+1)); printf 'Running test #%d...' "$i";
response=$(printf "*1\r\n\$4\r\nPING\r\n" | nc localhost $PORT);
if [ "$response" = '+PONG\r\n' ]; then
  printf ' PASSED'
else
  printf ' FAILED\nGot:\n%s\n\n' "$response"
fi;
sleep 0.1;

pkill redis-server;
That's just one example of a test. When a user sends the PING command, the expected response is PONG, but it is encoded and sent back as +PONG\r\n. The CLI output of this test run ($ ./test.sh) is:
Running test #1... FAILED
Got:
+PONG
So, it seems that the variable $response indeed contains what it should. I tried removing +, \r, \n, \r\n from the reference output to no avail, just to see if that would help. I'll have more complicated tests that include a character that needs to be escaped ($), such as \$5\r\nHello, in the response. By the way, manually setting response works as expected.
response='+PONG\r\n';
if [ "$response" = '+PONG\r\n' ]; then
  echo Equal
else
  echo Different
fi;
This prints Equal, as expected. After adding debug output through set -ex, I can see that $response stores +PONG\r, i.e., without \n.
Running test #1...++ printf '*1\r\n$4\r\nPING\r\n'
++ nc localhost 6380
+ response=$'+PONG\r'
+ '[' $'+PONG\r' = '+PONG\r\n' ']'
+ printf ' FAILED\nGot:\n%s\n\n' $'+PONG\r'
 FAILED
Got:
+PONG
Okay, so then setting the reference output to +PONG\r should work, right?
Running test #1...++ printf '*1\r\n$4\r\nPING\r\n'
++ nc localhost 6380
+ response=$'+PONG\r'
+ '[' $'+PONG\r' = '+PONG\r' ']'
+ printf ' FAILED\nGot:\n%s\n\n' $'+PONG\r'
 FAILED
Got:
+PONG
Clearly not. I tried wrapping response in {}, like this: if [ "${response}" = '+PONG\r' ]; then, to no avail. What am I missing? I'm also curious to know how and why \n got lost. I'm running it from zsh on a mac if that should be noted, but the shebang clearly tells it to use bash. If I execute ps -p $$ from the test script, I get 51547 ttys003 0:00.02 /bin/bash ./test.sh.
Asked by ivanbgd (111 rep)
Apr 17, 2025, 03:55 PM
Last activity: Apr 18, 2025, 05:43 AM