On 08/27/2010 05:20 PM, Joshua Lutes wrote:
On Fri, Aug 27, 2010 at 4:09 PM, Stuart Jansen <sjan...@buscaluz.org
<mailto:sjan...@buscaluz.org>> wrote:
echo "Warning: Unstable frobnicator" \
| egrep -i --color '^(warning|error)'
I was sort of hoping for something I could stick into a config file
or something that would work on all of the lines written to the
terminal. Anything like that?
That can be done easily enough. Just write yourself a filter, and pipe
the output of your command to the filter. The filter could be a
separate shell script, or a shell function. An example:
*****
TPUT=$(which tput)
if [[ -n $TPUT && -x $TPUT ]] ; then
R=`tput setaf 1; tput bold`
G=`tput setaf 2; tput bold`
Y=`tput setaf 3; tput bold`
X=`tput sgr0`
else
R=`echo -en "\\033[1;31m"`
G=`echo -en "\\033[1;32m"`
Y=`echo -en "\\033[1;33m"`
X=`echo -en "\\033[0;39m"`
fi
filter_stdout () {
while read line ; do
case "$line" in
*[Ee]rror*|*problem*)
echo -n "${R}"
;;
*[Ww]arning*)
echo -n "${Y}"
;;
esac
echo -e "$line${X}"
done
}
*****
Then, to filter & highlight your output, just pipe the command through
the function:
/usr/bin/my_command | filter_stdout
To make it a shell script instead of a function, just remove the
"filter_stdout() {" and "}" lines, stick a "#!/bin/bash" at the top, and
name the whole file "filter_stdout".
If you really want to put your strings "into a config file", I'd suggest
replacing the case statement with something like this:
echo "$line" | grep -qf error_patterns.txt && echo "${R}" || { echo
"$line" | grep -qf warning_patterns.txt && echo "${Y}" }
Then, put all your strings/patterns into the text files (one pattern per
line). This won't be quite as efficient, since you'd be reading the
strings files multiple times, but would certainly work. Of course, you
could also read those strings into variables in bash just once, and use
the patterns multiple times, but now things are getting more complex
than we probably want to discuss on the UUG.
At this point, I should point out that (depending on your particular
need, and how complex your filter will be) you may get more mileage by
using perl or another language, rather than staying in bash the whole
time. Then again, some would argue that perl is pathologically
eclectic, so use what works for you and your particular use case.
Now, I note that you mentioned wanting to filter "all of the lines
written to the terminal". That's a bit trickier, but still very doable,
of course. First, save a copy of stdout:
exec 3>&1
Then redirect stdout into the filter, with output going to the stdout
that you can see (the copy):
exec 1> >(filter_stdout >&3)
To redirect stderr instead of stdout, use fd "2" in place of fd "1". To
redirect both, make a copy of stderr (fd 2) on fd 4, and repeat the
redirection with 2 & 4 (in place of 1 & 3).
This will continue filtering *all* lines written to the terminal, so
after doing this, you no longer need to pipe individual commands into
the filter. This will highlight "echo error" or any other occurrence of
the strings in stdout, even just /usr/bin/my_command
However, be advised that by filtering stdout/stderr like that, you're
likely to break a lot of programs you try to run. stdout will no longer
be your terminal, so you'll get messages such as this (if you're also
redirecting stderr, this would also be in color, of course):
Vim: Warning: Output is not to a terminal
Filtering all output is likely to cause problems, so I'd recommend just
using the filtering function/script when needed, and just piping
into/through the filter at those times.
Frank
--
Frank Sorenson - KD7TZK
Linux Systems Engineer, DSS Engineering, UBS AG
fr...@tuxrocks.com
--------------------
BYU Unix Users Group
http://uug.byu.edu/
The opinions expressed in this message are the responsibility of their
author. They are not endorsed by BYU, the BYU CS Department or BYU-UUG.
___________________________________________________________________
List Info (unsubscribe here): http://uug.byu.edu/mailman/listinfo/uug-list