rakitzis / rc

rc shell -- independent re-implementation for Unix of the Plan 9 shell (from circa 1992)
Other
252 stars 23 forks source link

behaviour of && and -e #27

Closed TobyGoodwin closed 7 years ago

TobyGoodwin commented 8 years ago

I was just tweaking the documentation, and was looking at the text for the -e flag. I've never really thought too hard before about how && behaves under rc -e, but now that I have it seems somewhat counterintuitive.

; prompt='-e> ' rc -e
-e> true || echo that failed    # 1
-e> false || echo that failed   # 2
that failed
-e> true && echo that worked    # 3
that worked
-e> false && echo that worked   # 4
-e> true && false               # 5
; 

Cases 1, 2, and 3 are obviously correct. But 4 seems problematic. On the one hand, there's an obvious symmetry between 1 and 4. On the other hand, there's an asymmetry between 4 and 5.

My mental model is that the compound this && that && last succeeds if this and that and last all individually succeed, and fails otherwise. Yet as far as -e is concerned, the compound succeeds if all the elements succeed, or if any but the last fails.

I'm not really saying this is a bug, nor proposing to change it; sh behaves the same way. But I would be interested in hearing if anybody else thinks this is slightly murky, and thus worth describing clearly in the docs.

borkovic commented 8 years ago

Agreed, it is weird. You could further highlight the surprising behavior by printing $status after each command. Number 4 will print 1, but won't exit. Number 5 will exit without printing anything.

; cat j
echo '>>' begin $pid
false && echo that worked ; whatis status  # 4
true && false             ; whatis status  # 5
echo '>>' end $pid
; 
; echo '>' $pid; rc  j; echo '>' $pid
> 2043
>> begin 2234
status=1
status=1
>> end 2234
> 2043
; 
; echo '>' $pid; rc -e j; echo '>' $pid
> 2043
>> begin 2238
status=1
> 2043
; 

Maybe the following comment from the man page explains the observed behavior:

However rc -e does not exit if a conditional fails. 
A conditional is the test of an if () command, or the left hand side of the || operator.

It appears that the left hand side of the && operator also is considered a conditional.

TobyGoodwin commented 7 years ago

We sorted this in 08d7e12b (thanks!) but forgot to close this issue