0

In a bash file s.sh, I have an Executor function to which I pass the commands to be executed. Whenever some command does not work as expected, this function outputs the command.

Executor()
{
    if ! $*
    then
        echo "$*"
        exit 2
    fi
}

Now I am invoking this function -

Executor clangPath="Hello" make (This is used to set the value of clangPath variable as "Hello" in the makefile)

This caused an error -

./s.sh: line 5: clangPath=Hello: command not found
[./s.sh] Error: clangPath=Hello make

However executing the same command like this works fine

if ! clangPath="Hello" make
then
    echo "HelloWorld!"
fi

After looking at the error, I thought there might be a mistake with the string quotations, so I tried

exitIfFail clangPath='"Hello"' make

Even this resulted in an error -

./s.sh: line 5: clangPath="Hello": command not found
[./s.sh] Error: clangPath="Hello" make

What could be the reason for the error?

Sashank
  • 590
  • 7
  • 22

1 Answers1

1

If the purpose of the function is to execute some Bash expression, then print an error message, if the expression failed (returned non-zero status), then, there is a way to implement this via eval:

#!/bin/bash -

function Executor()
{
  eval "$@"

  if [ $? -ne 0 ]
  then
    echo >&2 "Failed to execute command: $@"
    exit 2
  fi
}

The $? variable holds the exit status of the previously executed command. So we check if it is non-zero.

Also note how we redirect the error message to the standard error descriptor.

Usage:

Executor ls -lh /tmp/unknown-something
ls: cannot access /tmp/unknown-something: No such file or directory
Failed to execute command: ls -lh /tmp/unknown-something


Executor ls -lh /tmp
# some file listing here...

The $@ variable is more appropriate here, as eval interprets things itself. See $* and $@.

Ruslan Osmanov
  • 20,486
  • 7
  • 46
  • 60
  • 1
    What's with the [`test $?` anti-pattern](http://mywiki.wooledge.org/BashPitfalls#cmd.3B_.28.28_.21_.24.3F_.29.29_.7C.7C_die)? A simple `if ! eval "$@"` would be shorter, clearer, and more consistent with the question, and `eval "$@" && return` is simpler still. – Toby Speight Sep 30 '16 at 12:55
  • @TobySpeight, it's a matter of preference. Some may think of it as an anti-pattern. But the style used in the answer looks pretty clear to me. – Ruslan Osmanov Sep 30 '16 at 13:00