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?

3
  • You could try if ! /usr/bin/ksh $* ... depending on where & what shell you're using? I dont have the ability to test here. Commented Sep 30, 2016 at 10:16
  • 1
    See Bash FAQ 050. Commented Sep 30, 2016 at 12:26
  • Eww, $*... I think you misspelt "$@". Commented Sep 30, 2016 at 12:51

1 Answer 1

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 $@.

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

2 Comments

What's with the test $? anti-pattern? A simple if ! eval "$@" would be shorter, clearer, and more consistent with the question, and eval "$@" && return is simpler still.
@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.

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.