Reputation: 2238
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
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 entire
x || 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
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