Socket I/O - Input/Output Unnamed pipes

I shall skip definition and details about sockets because you can find such information here and so let's open a socket for reading/writing using shell syntax

$ exec {file-descriptor}<>/dev{protocol}/{host}/{port}

╰─ #!/bin/bash exec 3<>/dev/tcp/rpcyber.pro/80 echo -e "GET / HTTP/1.1\n\n" >&3 cat <&3 HTTP/1.1 400 Bad Request Server: nginx/1.18.0 Date: Sat, 26 Nov 2022 10:00:05 GMT Content-Type: text/html Content-Length: 157 Connection: close

I have checked the logs of nginx but I was not able to understand why it replied with bad request but the idea is that this syntax can be used to access or create sockets. NOTE: /dev/tcp can only be used to communicate with an already existing socket, because TCP needs a reply, while UDP does not. We will see this in the following example:

╰─ #!/bin/bash exec 3<>/dev/tcp/localhost/1234 ./myscript.sh: connect: Connection refused ./myscript.sh: line 3: /dev/tcp/localhost/1234: Connection refused

Localhost is not listening on port 1234 and so we see this connection refused right from STDERR of exec command. But if we replace tcp with udp, we shall not see any error because UDP does not expect any response, it is a connectionless protocol as opposed to TCP which is a connection-oriented protocol

╰─ #!/bin/bash exec 3<>/dev/udp/localhost/1234 $ ./myscript.sh

Script executes with no error as we can create a file descriptor which connects port 1234 and random port generated for myscript.sh even though port 1234 is not listening because we UDP doesn't care about errors.

Now let's do something more interactive and use coproc to open netcat and listen to a port as a background process. Purpose of using coproc is not that netcat will run in background, it is that we can redirect data from stdin and to stdout of this process

╰─ #!/bin/bash #Use coproc to start netcat in background coproc nc -l localhost 1234 while read -r command; do case $command in date) date ;; name) hostname ;; ip) curl ifconfig.me ;; quit) break ;; *) echo -e "Usage:\nip -> display public IP\ndate -> display date\nname-> display hostname\n quit ->exit process" esac done <&"${COPROC[0]}" >&"${COPROC[1]}" # Get input for read command from STDIN of coproc which means stdin of netcat and redirect output towards stdout of netcate, otherwise data will display on this terminal as it defaults to stdout of process for this script