Reputation: 6303
What's the difference between
[ -e /usr/local/nagios ] && echo yes
and
if [ -e /usr/local/nagios ]; then echo yes
fi
And when is it right to use any of them?
Let's say I want to test if Nagios was compiled from source or installed through yum (the default installation location from source is /usr/local/nagios
and through YUM
it's /etc/nagios
) - then I will know where the plugins folder resides and it will allow me to pull the plugins from the Nagios server to the Nagios client and place them in the right directory.
So which approach is the best to achieve this goal?
Thanks in advance
Upvotes: 4
Views: 14652
Reputation: 5742
Adding something practical to the other technical answers here, one reason to use if ...; then do-stuff; fi
over ... && do-stuff
, regardless of whether we use test
or [ ]
for the condition, is the resulting exit code, and exit codes should usually express success or failure:
$ touch foo.txt
$ if test -e foo.txt; then echo "do stuff"; fi
do stuff
$ echo $?
0
$ test -e foo.txt && echo "do stuff"
do stuff
$ echo $?
0
$ if test -e bar.txt; then echo "do stuff"; fi
$ echo $?
0
$ test -e bar.txt && echo "do stuff"
$ echo $?
1
In other words, using if ...
expresses that the condition being false is not a failure but an expected and perfectly fine thing to happen, it just means don't run do-stuff
. Using ... &&
expresses that the condition being false not only means don't run do-stuff
, it means the net result is a failure, that something has gone wrong.
While it's true that most things you can do with if ...
you can do with &&
, ||
and (...)
, it's much harder to understand the intention when read by a human, and code is for both machines and humans:
$ (test -e foo.txt && echo "do stuff") || true
do stuff
$ echo $?
0
$ (test -e bar.txt && echo "do stuff") || true
$ echo $?
0
And yes, we don't need ( ... )
here, but its even harder to understand the intention without them. Is the ||
for if do-stuff
fails or if the condition is false? None of the time and effort spent reasoning through such things or looking for context clues is necessary to understand the intention of if ...
. This becomes more and more true the more complicated the conditions. Imagine adding multiple "else if ..." sub-conditions and a final "else" clause using &&
and ||
.
Upvotes: 2
Reputation: 1336
[
is usually an other name for the command test
, just expecting a ]
as last argument. You could actually write the two commands:
test -e /usr/local/nagios && echo yes
and
if test -e /usr/local/nagios; then echo yes; fi
test
and [
are just shell commands performing checks and returning 0
or 1
, that's why you can use it like this [ -e file ] && echo exists
(or test -e file && echo exists
).
When writing a script a few line long, I usually find the use of if
clearer and more explicit.
As of your other question, relying on hard coded paths is usually a bad idea (you can install from source to another directory and yum
may install nagios somewhere else in the future or depending on some configuration). I suggest you try querying yum
to see if it has nagios installed (with yum info nagios
or yum list installed | grep nagios
for example). Then, if nagios wasn't installed with yum, but the binary is in your PATH
, you can try which nagios
which will give you the full path of the nagios
binary.
Upvotes: 9
Reputation: 5298
Option1:
[ -e /usr/local/nagios ] && echo yes
Here, you are using the Logical AND operator(&&). The second operand will be evaluated only if the first one returns true. At first "[ -e /usr/local/nagios ]" will be evaluated. That is, checks if /usr/local/nagios exists. If it doesn't exist, the next part "echo yes" will not be evaluated. So, effectively "echo yes" will be done only if /usr/local/nagios exists, thus yes will be printed out. else it will not.
Option2:
if [ -e /usr/local/nagios ]
then
echo yes
fi
This is just another way of doing the same thing. Here, we check if /usr/local/nagios exists. If it exists, then print yes. else do nothing.
Eventhough the first option looks smarter, considering readability, I would go for option 2. Personal choice i would say.
Upvotes: 3