yash
yash copied to clipboard
for loop wrong exit status
The following shell script should print 1 according to POSIX:
for x in y; do
! continue
done
echo $?
But it prints 0 on yash.
Can you pinpoint the statements that require that behavior in POSIX?
Note that the current behavior is the intended consequence of ba43abb7d95b656ce7470b11b91a21995fd2b525. See https://osdn.net/projects/yash/ticket/46224.
Can you pinpoint the statements that require that behavior in POSIX?
XCU 2.15 Special Built-in Utilities/continue/EXIT STATUS
0 Successful completion.
XCU 2.9.2 Pipelines/Exit Status
If the pipeline does not begin with the ! reserved word, the exit status shall be the exit status of the last command specified in the pipeline. Otherwise, the exit status shall be the logical NOT of the exit status of the last command. That is, if the last command returns zero, the exit status shall be 1; if the last command returns greater than zero, the exit status shall be zero.
XCU 2.9.4 Compound Commands/The for Loop/Exit Status
The exit status of a for command shall be the exit status of the last command that executes. If there are no items, the exit status shall be zero.
Note that the current behavior is the intended consequence of ba43abb. See https://osdn.net/projects/yash/ticket/46224.
That ticket is about return
only. See XCU 2.15 Special Built-in Utilities/return/EXIT STATUS
The value of the special parameter '?' shall be set to n, an unsigned decimal integer, or to the exit status of the last command executed if n is not specified.
Thanks, but I don't think your quotes conclude that your script should print 1 rather than 0.
The point is that the negated pipeline does not finish at all, either successfully or unsuccessfully. It just gets aborted without producing any exit status. The situation can be made clearer by rewriting with more compound commands:
for x in y; do
if continue; then
false
else
true
fi
done
echo $?
The false
or true
command is never executed, so the if command never runs till the end. The echo
shows the exit status of continue
, not that of if
.
for x in y; do
! {
continue
# This `echo` is never executed as it follows `continue`.
echo oops
# ... which means the end of the `{ ... }` command is never reached.
}
# ... which means the end of the enclosing `! ...` command is never reached.
done
echo $?
Since the end of the !
command is not reached, you'll never see the exit status of the !
command.
The point is that the negated pipeline does not finish at all, either successfully or unsuccessfully. It just gets aborted without producing any exit status.
Is this what POSIX says or what yash does?
That's my interpretation of POSIX, and what yash does.