Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
Why don't you use log file monitoring? –  Michael Hampton Apr 5 '14 at 17:09
Zabbix's built in log file monitoring is great at alerting me that something went wrong, but I haven't managed to get it to record any surrounding lines. Even using the output argument to log, I can't seem t make it capture more than the line that triggered it. If you know of a way to make this work, please share it with me. –  skyler Apr 5 '14 at 17:53

2 Answers 2

up vote 1 down vote accepted

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:

echo "0" >/tmp/numberoflines
while [ 1 ]
    NUMBER=$(cat /tmp/numberoflines)
    LINES=$(wc -l < /var/log/uwsgi.log)

    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;

sleep 5;
echo "$LINES" >/tmp/numberoflines
share|improve this answer

You must turn off word splitting in bash, eg, by clearing IFS:

export IFS=""
set NEWVAR=`your tail|grep expression`

Now echo $NEWVAR has the newlines.

share|improve this answer
This will run once and capture tail's output, no? Will it follow the file as it's written to by the app that I'm logging? –  skyler Apr 5 '14 at 17:57
Unfortunately that didn't work export IFS="" tail -Fn0 /var/log/uwsgi.log | grep "Exception:" -A 100 | (read errorlines; echo "$errorlines" > /tmp/errorlines.txt) –  skyler Apr 5 '14 at 18:02
I marked up this answer because I didn't know about the IFS trick for capturing multiline output into a variable. –  pdwalker Jan 14 at 1:42

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.