J

No redis-cli? No problem

21 Nov 2022

Today while performing some basic networking connectivity tests between Kubernetes namespaces, I found myself without redis-cli which is what I’d usually reach for to test connectivity to a Redis instance.

The container also didn’t have nc which left me in a bit of a bind as to what to do. I could have just installed the packages and shipped a new image but instead, I opted to use what I had: bash and exec.

I ended up with the following incantation which relies on abusing using bash’s inbuilt /dev/tcp device file for opening a socket to the hostname and sending the request.

exec 3<>/dev/tcp/<hostname>/<port> && echo -e "PING\r\n" >&3 && cat <&3

Command break down

exec 3<>/dev/tcp/<hostname>/<port> This causes file descriptor 3 to be opened for reading and writing on the specified TCP/IP socket. This is a special form of the exec statement.
echo ... >&3 Build the request you intend to send to the remote. In my case, PING followed by a carriage return and newline.
cat <&3 Reads the response back to write out.

While used for Redis here, this approach can also be applied to UDP (swap to /dev/udp ) and HTTP requests (build a HTTP compliant request)!

Less exotic alternatives

# nc
(printf "PING\r\n"; sleep 1) | nc <hostname> <port>
# telnet
telnet <hostname> <port>