Linux – Capture piped multiline grep output into a variable

bashgreplinuxtail

I'm using Zabbix's zabbix_sender.sh script to push exception stack traces to my remote Zabbix monitoring server.

zabbix_sender.sh requires a key and a value for any data that it sends. It can read data from stdin, but this overrides any key variable specified. Because my stdin data isn't formatted like Zabbix expects, I need to pass in "value" as an argument. Hopefully this provides some context.

What I want to accomplish is capturing the multiline result from grep into a variable, preserving newlines, so that I can call the zabbix_sender.sh script with that variable as an argument.

What I've tried so far looks like this:

tail -Fn0 /var/log/uwsgi.log | grep "Exception:" -A 100 | (read tback; /usr/local/zabbix/bin/zabbix_sender -z myzserver.com -s MyHostName -k uwsgi_traceback -o $tback)

As best I can tell, that never invokes zabbix_sender.sh.

To test, I've tried using this command, which doesn't seem to work either:

tail -Fn0 /var/log/uwsgi.log | grep "Exception:" -A 100 | (read errorlines; echo "$errorlines" > /tmp/errorlines.txt)

The /tmp/errorlines.txt file is never created.

How can I capture grep's output lines into a variable so that I can call another script with that variable as an argument?

Best Answer

The problem is the tail part; since it is in continuos mode it wont ever spit out something for "read" to read.

This should work:

#!/bin/bash
echo "0" >/tmp/numberoflines
IFS=''
while [ 1 ]
do
    NUMBER=$(cat /tmp/numberoflines)
    LINES=$(wc -l < /var/log/uwsgi.log)
    DIFFERENCE=$(($LINES-$NUMBER))

    if [ $DIFFERENCE != 0 ]; then
            exception=$(tail -n $DIFFERENCE /var/log/uwsgi.log | grep "Exception:" -A 100)
           /zabbix/bin/zabbix_sender -z myzserver.com -s MyHostName -k uwsgi_traceback -o $tback) $exception;
    fi

sleep 5;
echo "$LINES" >/tmp/numberoflines
done