https://who23.github.io/2020/12/03/sockets-in-your-shell.html

Something I learned recently and I thought was amazing - you can create sockets straight from your shell! Well, assuming you use bash or zsh - from some surface level digging, I couldn’t find anything for fish.

Here’s how it works:

bash

Bash supports tcp and udp connections out of the box, and does so with an imaginary device in /dev. Enter

$ echo "text!" > /dev/$PROTO/$HOST/$PORT

And you’ll create a connection to HOST:PORT. $PROTO can be tcp or udp. If the connection can’t be made, writing to/reading the file will fail.

Along with being easy to access from the terminal, it’s very handy for scripts, especially if you don’t have nc/telnet. For example, if a local build of a web app runs on port 8000, you can check if it’s running with:

#!/bin/bash
if [ exec 1>/dev/null 2>/dev/null 3>/dev/tcp/localhost/4000 ] ; then
	echo "server up!"
else
	echo "server down."
fi

And then use that information somewhere else.

If you’re unfamiliar, exec is used here to create the file to write to (>), with file descriptor 3 referring to it and thus the connection.

We can use exec to create a connection we can read and write to with <>, and create a super simple curl:

#!/bin/bash
exec 3<>/dev/tcp/"$1"/80
echo -e "GET / HTTP/1.1\\n" >&3
cat <&3

$ ./simplecurl www.google.com
HTTP/1.1 200 OK
Date: Thu, 03 Dec 2020 00:57:30 GMT
Expires: -1
....
<google website>

I’m sure you can see the power of being able to open sockets with bash alone. Go play around with it!

zsh

zsh has an external module you can load in order to use it’s socket capabilities. It doesn’t support udp like bash, but it’s more powerful in a few ways!

To load the module, put the following in your .zshrc or run it in your shell:

$ zmodload zsh/net/tcp