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>