0

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.

3 Answers 3

1

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!)

Sign up to request clarification or add additional context in comments.

1 Comment

I also imagine that the unquoted $1 really should be double quoted "$1" but it is of course possible that you actually know what you are doing and have a good reason to want the shell to do whitespace splitting and wildcard expansion of the value in $1. If not (and/or especially if you don't understand what I'm saying), it should definitely be "$1" instead. Or perhaps you are looking for ${1:+"$1"} which ends up quoted if non-empty.
1

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.