Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: &&||



On Mon, 19 Feb 2018 13:12:20 -0800
Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:

> function test ()
> {
>      _aaray=`ls`

You never need to use output from ls in a shell unless you need long
output like ls -l (and there are ways round that, too).  This should be

_aarray=(*)

and you get the full power of globbing if you wanted to vary the
contents in some way.  Strictly, I suppose it should be

_aarray=(*(N))

to give you an empty array rather than an error if there are no files
that don't begin with a dot.

>      [ true ] && { print -l "${ _aaray[@]}" | GREP_COLOR='01;33' egrep 

Do you mean just "true"?  Not sure what putting this in square brackets
is supposed to achieve.  It does work, but purely by virtue of the fact
that the string "true" has non-zero length --- as does the string
"false", which is one of several reasons I'd avoid this.

> --color=always "$1"\
>
> | GREP_COLOR='01;31' egrep --color=always "$2" }\
> 
> || echo bust!

If you read the documentation about && and || (OK, OK, I'm joking, I'm
joking) you'll find the statement:

  Both operators have equal precedence and are left associative. 

That's written for geeks, but what it means is the shell simply looks
through from left to right, taking the &&s and ||s as they come:

- If it finds "&&" at any point, it executes the following chunk if the
previous returned status true.  Otherwise, it skips it and looks for any
further "&&" or "||".

- If it finds "||" at any point, it executes the following chunk if the
previous returned status false.  Otherwise, it skips it and looks for
any further "&&" or "||".

I've skipped over the fact that actually it may not have executed
the chunk before the "&&" or "||" it's looking at.  So where I
said "the previous status returned" you should really think of
"the last status of anything it did execute was...".  So

false && true || true

- runs false to get status (surprise!) false.

- looks at the "&&" and decides "nah, skip the next bit".

- looks at the "||" and still has status false, so executes the true.

That should give you enough of a hint to follow any combination.

Note this is not how && and || work in C, or even in zsh's own
arithmetic context which is much more like C than the standard shell
syntax is.

You can affect the precedence with braces, but they need to surround the
"&&" or "||" expression you want to protect.  In your case you've simply
surrounded a pipeline which would be run in one go anyway:

% echo one && echo one | sed -e s/o/a/
one
ane

is just the same as

% echo one && { echo one | sed -e s/o/a/ }
one
ane

and sticking more of the poor suffering &&s and ||s after doesn't change
it, either.

> }

pws



Messages sorted by: Reverse Date, Date, Thread, Author