[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Syntax for if test
From: |
Greg Wooledge |
Subject: |
Re: [Help-bash] Syntax for if test |
Date: |
Mon, 5 Dec 2011 10:51:51 -0500 |
User-agent: |
Mutt/1.4.2.3i |
On Mon, Dec 05, 2011 at 09:21:36AM -0600, Bill Gradwohl wrote:
Let's start here:
> Lastly, I've read up on [[ ]] numerous times in man bash and I can't quite
> wrap my head around it. Can someone point at an alternate explanation on
> the features and benefits of using [ ] vs [[ ]] ?
http://mywiki.wooledge.org/BashFAQ/031
> What I want to say is :
> if a is true or (b is true and c is true) then do something.
if [[ a || b && c ]]; then
something
fi
Bearing in mind that && has a higher precedence than ||, making the
parentheses redundant. For clarity, you could add them:
if [[ a || (b && c) ]]; then
something
fi
> I can't seem to get the syntax correct using a standard [ ] notation.
It cannot be done portably with a *single* [ ... ] command. The syntax
just isn't that flexible. If you want POSIX compatibility, you must
use several [ ... ] commands instead:
if [ a ] || [ b ] && [ c ]; then
something
fi
If you require grouping, then:
if [ a ] || { [ b ] && [ c ]; }; then
something
fi
Note the semicolon inside the curly braces. It's required in a single-line
command grouping.
> if [ $(some executable) -o ( $(some executable) -a $(some executable ) ];
Do not attempt to use -o or -a. Ever. Either use [[ a && b ]] or use
[ a ] && [ b ]. One rule of thumb here is that if you are writing for
POSIX you should use [ a ] && [ b ]; and if you are writing for bash, then
you should use [[ a && b ]].
> Also, man bash says:
> ( expression )
> Returns the value of expression. This may be used to
> override the normal precedence of operators.
>
> No matter what I try I can't seem to get the syntax correct to use ( ) as
> shown above.
It works fine in [[ ... ]]. If you want to use it inside [ ... ] then
you would have to escape it, but please, don't do that. Just use multiple
[ ... ] commands instead. That way your code will be portable and readable.
> if [ $(echo "${templateMachine}"|egrep -q '\.') -a $(grep -q
> "${templateMachine}" /etc/hosts|grep -q $(hostname -s)) ] || [
> "${templateMachine}" == $(hostname -s) ]; then
grep -q | grep -q is not right. The first one won't write anything for
the second one to read.
do_it=0
if [[ $templateMachine = "$(hostname -s)" ]]; then
do_it=1
elif [[ $templateMachine = *.* ]] &&
grep "$templateMachine" /etc/hosts | grep -q "$(hostname -s)"; then
do_it=1
fi
if ((do_it)); then
something
fi
That's how I'd write it, assuming I fixed your greps correctly. You
should choose a more meaningful flag variable name than do_it; I can't
pick one because I don't know what it's doing.