user1527227
user1527227

Reputation: 2238

error check function in bash

In bash scripting, you can check for errors by doing something like this:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

If you have a large script, constantly having to do this becomes very tedious and long. It would be nice to write a function so all you have to do is pass the command and have it output whether it failed or succeeded and exiting if it failed.

I thought about doing something like this:

function cmdTest() {
if $($@); then
    echo OK
else
    echo FAIL
    exit
fi
}

So then it would be called by doing something like cmdTest ls -l, but when Id o this I get: ls -l: Command not found.

What is going on? How can I fix this?

Thank you.

Upvotes: 0

Views: 114

Answers (2)

chepner
chepner

Reputation: 530833

Your cmdtest function is limited to simple commands (no pipes, no &&/||, no redirections) and its arguments. It's only a little more typing to use the far more robust

{ ... ;} && echo OK || { echo Fail; exit 1; }

where ... is to be replaced by any command line you might want to execute. For simple commands, the braces and trailing semi-colon are unnecessary, but in general you will need them to ensure that your command line is treated as a single command for purposes of using &&.

If you tried to run something like

cmdTest grep "foo" file.txt || echo "foo not found"

your function would only run grep "foo" file.txt, and if your function failed, then echo "foo not found" would run. An attempt to pass the entirex || y` to your function like

cmdTest 'grep "foo" file.txt || echo "foo not found"

would fail even worse: the entire command string would be treated as a command name, which is not what you intended. Likewise, you cannot pass pipelines

cmdTest grep "foo" file.txt | grep "bar"

because the pipeline consists of two commands: cmdTest grep "foo" file.txt and grep "bar".

Shell (whether bash, zsh, POSIX sh or nearly any other kind) is simply not a language that is useful for passing arbitrary command lines as an argument to another function to be executed. The only work around, to use the eval command, is fragile at best and a security risk at worst, and cannot be recommended against enough. (And no, I will not provide an example of how to use eval, even in a limited capacity.)

Upvotes: 2

anubhava
anubhava

Reputation: 784878

Use this function like this:

function cmdTest() { if "$@"; then echo "OK"; else return $?; fi; }

OR to print Fail also:

function cmdTest() { if "$@"; then echo "OK"; else ret=$?; echo "Fail"; return $ret; fi; }

Upvotes: 1

Related Questions