Bash: TCP/Internet connection handling
There’re many problems nowadays, which could easier be solved through the internet. In this post I descripe how to address these problems by bash alone.
The standard way to connect to a server in the internet, is to embed the connection stream
exec 3<>/dev/tcp/$server/$ircPort || echo "Some text or doing, if connecting failed"
So for example if you want to get the first page of this blog, you might run
exec 3<>/dev/tcp/techoverflow.net/80 && echo -e "GET /index.html HTTP/1.1\r\nhost: techoverflow.net\r\nConnection: close\r\n\r\n" >&3 && cat <&3
However still more complex connections can be build, like this little irc bot
#! /bin/bash
# Here you might do some configs
nickname="testBot"
server="chat.freenode.net"
ircPort=6667
channels=(\#ubuntu) # You might add multiple channels to join like this:
# (channel1 channel2 channel3), however ensures that you escape each #
logFile=log.log
# do connection and joining stuff
echo "Connecting to server ..."
exec 3<>/dev/tcp/$server/$ircPort || echo "Connection failure! ..."
echo -ne "NICK ${nickname}\r\n" >&3
echo -ne "USER ${nickname} localhost localhost :simple irc bash bot\r\n" >&3
echo "Connect to all channels ..."
for ind in ${!channels[*]}
do
echo -ne "JOIN ${channels[$ind]}\r\n" >&3
done
# program main loop
while true
do
# read the next line from the connection
line=$(head -n 1 <&3)
# check, if (stream) connection closed (network error or something like that)
# Note, that IRC Server never send empty lines
if [ "$line" == "" ] || [ "$(ls /proc/$$/fd | grep -w '3')" != "3" ]
then
echo "Connection to irc server was closed! Quitting ..."
break
fi
# output on screen (Note, that the \n was removed by the head command)
echo "Reciving ..."
printf "%s\n" "$line" | hd
# reply PONG to PING else the IRC Server assumes that you're not listening
# anymore and will kick you
if [ "${line:0:5}" == "PING " ]
then
echo -n "PONG ${line:5}" >&3
echo -ne "\r\n" >&3
fi
# Here more interaction stuff can be applied
echo $line >> $logFile
done
exec 3>&- # close output connection
exec 3<&- # close input connection