Just installed FreeBSD but failed boot

in tcsh, it does not echo yes
[...]
in csh, it does not echo yes
I wonder which csh this could be nowadays if not tcsh? :-/

But indeed, another example how C shells are just broken.

Of course it SHOULD echo "yes". What's after || is only executed if the last exit code was non-zero. What's after && is only executed if the last exit code was zero. Simple as that. The C shell seems to apply some broken magic instead...
 
I'm not going to argue what one should use for scripting, merely reporting what the shells I have installed do.
 
I'm not going to argue what one should use for scripting, merely reporting what the shells I have installed do.

% diff /bin/csh /bin/tcsh
%

Like many, I prefer csh for interactive use, and only sh for scripting. That said ...

I wonder if we can bring this thread back to the OP's issue, if he hasn't given up?

I last sought info in post #23
 
I wonder which csh this could be nowadays if not tcsh? :-/

But indeed, another example how C shells are just broken.

Of course it SHOULD echo "yes". What's after || is only executed if the last exit code was non-zero. What's after && is only executed if the last exit code was zero. Simple as that. The C shell seems to apply some broken magic instead...
That’s because AND is greedy by default while OR in contrary is NOT lazy.
 
(true || false) && echo yes in csh/tcsh produces "yes"

Based on this from zirias@
What's after || is only executed if the last exit code was non-zero. What's after && is only executed if the last exit code was zero.

true never returns non-zero, it's as if the csh/tcsh are treating the whole thing as:
true || (false && echo yes)

but bash/sh are treating it as:
(true || false) && echo yes
 
Based on this from zirias@
What's after || is only executed if the last exit code was non-zero. What's after && is only executed if the last exit code was zero.

true never returns non-zero, it's as if the csh/tcsh are treating the whole thing as:
true || (false && echo yes)

but bash/sh are treating it as:
(true || false) && echo yes

Except there just is no "precedence" at all in a POSIX/bourne shell, see
Code:
$ false && true || echo yes
yes

It's just strictly left to right and each || or && decides whether to execute the following command or not based on the exit code of the command that was last executed.
 
  • Like
Reactions: mer
Except there just is no "precedence" at all in a POSIX/bourne shell, see
Code:
$ false && true || echo yes
yes

It's just strictly left to right and each || or && decides whether to execute the following command or not based on the exit code of the command that was last executed.
I'm thinking we are going to "agree to disagree" on something here. I'd have to dig out my K&R and C reference stuff to be sure but I don't know or have an opinion as to which is correct. If there is no precedence in POSIX/bourne shell then it looks like POSIX/bourne is actually treating it as (true || false) && echo yes which implies some sort of precedence or grouping.
Instead of your false && true || echo yes do
false || true && echo yes
I get the same result as the original, which implies bash is doing (false || true) && echo yes Paren grouping around the || operator.
To me that implies strongly that bash/sh/POSIX treats || differently in a precedence order.

true || false means "false" is executed, yes?
false && echo yes means echo is not executed, no?

Based on what you are saying, it seems to me that without parens, csh/tcsh is acting exactly as you describe.
exit code of true is causing false to be executed, exit code of false is not causing echo to be executed.

My takeaway from this whole thing is "Parens and grouping are important. Say what you mean don't assume something else is going to do what you want".
And yes, if I need to do scripting in a shell I do it in bash or sh, but I do prefer csh/tcsh for interactive shell.
 
true || false means "false" is executed, yes?
No. true has a 0 exit code. As it IS executed, $? is 0, based on that, the shell does NOT execute the command following ||.
false && echo yes means echo is not executed, no?
Yes, obviously. But in the whole line, false is never executed.

I assume you are still thinking "too complicated". The shell does not evaluate any expressions here. What happens is like this:
Bash:
true \      # just a new command, always executed, $? is 0 now
|| false \  # as $? is 0, the command following the || is ignored
&& echo yes # $? is still 0, so the command following the && is executed

See also these experimental snippets:
Bash:
$ true || false
$ echo $?
0
$ if true || false; then echo yes; fi
yes
$ if true || false && false; then echo yes; fi
$ if false && false || true; then echo yes; fi
yes
$

Whether this behavior of the shell is good, logical, whatever, you could probably argue a lot about. I personally think it does make perfect sense, because as mentioned above, the shell does not evaluate any expression here but really executes a script step by step. But well ...

Anyways, this is the standard POSIX behavior of a bourne shell.

And so it is ONE of many issues with C shells. They try to "be clever" (in, let's do it more like C, so C programmers understand it), but exposing different behavior in such things just causes confusion and destroys portability. Disclaimer: Yes, I really really dislike shells that don't conform to POSIX by design ?

edit:
My takeaway from this whole thing is "Parens and grouping are important. Say what you mean don't assume something else is going to do what you want".
Also careful with that. If you'd write true || (false && echo yes), this would mean the false && echo yes part would be executed by a subshell, IOW, a child process. This might not be what you want. Sure, it WOULD have the effect of not outputting yes, because in the subshell, the false is executed unconditionally, setting $? to something non-zero, therefore the && would make the shell ignore the following command. (edit2: well, if the subshell would be executed at all that is ... which it won't here, because it's guarded by a || ... but at least same result in the end!)
But that's not the actual purpose of parentheses in bourne shell, their purpose is to execute something in a subshell.
 
Back
Top