I am trying to implement a simple log server in Bash. It should take a file as a parameter and serve it on a port with netcat.
( tail -f $1 & ) | nc -l -
bobbogo answer works but requires a intermediary pid file.
You can leverage the process substitution feature >()
which works like|
but without waiting for tail
to finish
tail -f $1 > >(nc -l -p 9977) & pid=!
This works for me (SLES Linux):
tail -F xxxx | tee -a yyyy &
export TAIL_PID=`jobs -p`
# export TEE_PID="$!"
The ps|grep|kill
trick mentioned in this thread would not work if a user can run the script for two "instances" on the same machine.
jobs -x echo %1
did not work for me (man page not having the -x
flag) but gave me the idea to try jobs -p
.
Maybe you could use a fifo, so that you can capture the pid of the first process, e.g.:
FIFO=my_fifo
rm -f $FIFO
mkfifo $FIFO
tail -f $1 > $FIFO &
TAIL_PID=$!
cat $FIFO | nc -l -p 9977
kill $TAIL_PID
rm -f $FIFO
Finally, I have managed to find the tail process using ps
. Thanks to the idea from ennuikiller.
I have used the ps
to grep tail from the args and kill it. It is kind of a hack but it worked. :)
If you can find a better way please share.
Here is the complete script:
(Latest version can be found here: http://docs.karamatli.com/dotfiles/bin/logserver)
if [ -z "$1" ]; then
echo Usage: $0 LOGFILE [PORT]
exit -1
fi
if [ -n "$2" ]; then
PORT=$2
else
PORT=9977
fi
TAIL_CMD="tail -f $1"
function kill_tail {
# find and kill the tail process that is detached from the current process
TAIL_PID=$(/bin/ps -eo pid,args | grep "$TAIL_CMD" | grep -v grep | awk '{ print $1 }')
kill $TAIL_PID
}
trap "kill_tail; exit 0" SIGINT SIGTERM
while true; do
( $TAIL_CMD & ) | nc -l -p $PORT -vvv
kill_tail
done
Not an ideal answer, but I found a workaround for a logger daemon I worked on:
#!/bin/sh
tail -f /etc/service/rt4/log/main/current --pid=$$ | grep error
from $info tail:
--pid=PID
with -f, terminate after process ID, PID dies
how about this:
jobs -x echo %1
%1
is for first job in chain, %2
for second, etc. jobs -x
replaces job specifier with PID.