Reputation: 1956
I have following code in my build script:
if [ -z "$1" ]; then
make -j10 $1 2>&1 | tee log.txt && notify-send -u critical -t 7 "BUILD DONE"
else
make -j10 $1 2>&1 | tee log.txt | grep -i --color "Error" && notify-send -u critical -t 7 "BUILD DONE"
fi
I tried to optimize it to:
local GREP=""
[[ ! -z "$1" ]] && GREP="| grep -i --color Error" && echo "Grepping for ERRORS"
make -j10 $1 2>&1 | tee log.txt "$GREP" && notify-send -u critical -t 7 "BUILD DONE"
But error thrown in make line if $1 isn't empty. I just can't figure out how to pass command with grep pipe through the variable.
Upvotes: 0
Views: 116
Reputation: 189926
Like others have already pointed out, you cannot, in general, expect a command in a variable to work. This is a FAQ.
What you can do is execute commands conditionally. Like this, for example:
( make -j10 $1 2>&1 && notify-send -u critical -t 7 "BUILD DONE" ) |
tee log.txt |
if [ -z "$1" ]; then
grep -i --color "Error"
else
cat
fi
This has the additional unexpected benefit that the notify-send
is actually conditioned on the exit code of make
(which is probably what you intended) rather than tee
(which I would expect to succeed unless you run out of disk or something).
(Or if you want the notification regardless of the success status, change &&
to just ;
-- I think this probably makes more sense.)
This is one of those rare Useful Uses of cat
(although I still feel the urge to try to get rid of it!)
Upvotes: 1
Reputation: 74695
As mentioned in @l0b0's answer, the |
will not be interpreted as you are hoping.
If you wanted to cut down on repetition, you could do something like this:
if [ $(make -j10 "$1" 2>&1 > log.txt) ]; then
[ "$1" ] && grep -i --color "error" log.txt
notify-send -u critical -t 7 "BUILD DONE"
fi
The inside of the test is common to both branches. Instead of using tee
so that the output can be piped, you can just indirect the output to log.txt
. If "$1"
isn't empty, grep
for any errors in log.txt
. Either way, do the notify-send
.
Upvotes: 1
Reputation: 58978
You can't put pipes in command variables:
$ foo='| cat'
$ echo bar $foo
bar | cat
The linked article explains how to do such things very well.
Upvotes: 1