Couple of years ago I googled for a simple bash IRC logging bot that I could start on my router to log some channels. I've found a very simple script that worked but didn't handle PINGs from the server. So I extended it a bit trying to keep it as simple as possible.
root@alix:~# cat ./irclogbot.sh #!/bin/sh nick="blb$$" channel=testchannel server=irc.freenode.net config=/tmp/irclog [ -n "$1" ] && channel=$1 [ -n "$2" ] && server=$2 config="${config}_${channel}" echo "NICK $nick" > $config echo "USER $nick +i * :$0" >> $config echo "JOIN #$channel" >> $config trap "rm -f $config;exit 0" INT TERM EXIT tail -f $config | nc $server 6667 | while read MESSAGE do case "$MESSAGE" in PING*) echo "PONG${MESSAGE#PING}" >> $config;; *QUIT*) ;; *PART*) ;; *JOIN*) ;; *NICK*) ;; *PRIVMSG*) echo "${MESSAGE}" | sed -nr "s/^:([^!]+).*PRIVMSG[^:]+:(.*)/[$(date '+%R')] \1> \2/p";; *) echo "${MESSAGE}";; esac done
PING's are handled in the line 22. Lines 23-27 are only added to make output readable and could be removed to log raw data.
The feedback inside of the 'while' loop allows me to use the script as a simple client too. IRC commands written into the $config file will be executed. For example one can send a text message into the channel by writing the following command:
echo "PRIVMSG #testchannel :Testing bash bot. Ignore it" >> /tmp/irclog_testchannelwhich makes it possible to re-purpose the bot by adding additional logic.
Insted of nc one can use telnet and in this case only busybox internal commands will be used
5 comments:
That`s just awesome. I was about to write my own bash script for logging but failed. Then I found yours and it`s exactly what I wanted to do. Best of all: I know what I did wrong now and understood how easy it really is :)
Thanks a lot
Erik
Thanks for sharing this. It was very useful to me.
I have changed a few things to avoid using nc, and use Bash built-in TCP sockets.
---
# Open the TCP connection.
exec 3<>/dev/tcp/$SERVER/$PORT
...
# Process each server command and logs everything.
while read -u 3 MESSAGE
do
MESSAGE=$(sed 's/\r//' <<< $MESSAGE )
echo "$(date -u +'%F %T') $MESSAGE" >>$LOG
case "$MESSAGE" in
yes, you can use bash sockets too but as I mentioned already neither nc nor bash is available on an embedded system with the busybox and ash. Replacing nc with telnet makes the script working on my router too.
This script works great. I've tried nc, telnet and bash builtin tcp. I have two tips for others reading this and trying.
1. If you are using the bash tcp code posted above, you can scrap the config file and redirect the output on your echos with '>&3' instead. Like so:
echo -e "NICK ${nick}" >&3
echo -e "USER $nick +i * :$0" >&3
(sleep 1;echo -e "JOIN #${channel}" >&3) &
2. Also as seen above, I noticed some servers was not ready to accept JOIN right away so I ran it in a subshell with a sleep before. The '&' character makes the commands run in the background while the script in the main shell continues as normal.
Sometimes first reply to ping server not work, why?
Post a Comment