New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
revisit exit code of while
builtin
#4982
Comments
How would you like it to behave? Return 0 when the loop has been run at least once, 1 otherwise? As best as I can tell, in bash it just always returns 0. |
I like the general principle of "if it's run at least once" but I feel like "if it never runs this is unexpected behavior/an error" is too big of an assumption to make and we'll just get complaints about it later (if anyone actually cares about these things). I think it should just return 1 in case there was an error evaluating the target (i.e. target does not exist). |
But it's not? A return of 1 isn't "unexpected behavior". It's just a false return. It's something you have to deal with all the time, and which happens for quite trivial reasons, and which has no huge effect. It's another way to convey information, not a big issue.
If the "target" does not exist, that would warrant an error message, not just a return value of 1. |
Well, yes and no. An error message is for the user, but the return code is for programmatic evaluation (which I understand you already cover with the "not just" in your statement). But my point is that nothing else explicitly warrants a non-zero return code for I understand that a non-zero return code is not code for "error occurred," but as you mention, it is intended to evaluate to Users wishing to explicitly take an action based on the result of a condition would be best served with Additionally, you have to consider the return code in the context of the script or function, as I initially mentioned. Given a function consisting solely of the following: function foo
if bar
# do something
end
end It is understandable why the function would return non-zero if the But for a function that looks like this: function foo
bar | while read -l baz
# do something
end
end It really doesn't make sense for the default behavior here to be for the function return non-zero. If anything, in this case the return code of |
I'm not sure that line of reasoning works. "For I think it's reasonable to say that the point of
I agree.
That's more debatable. In this specific case you might want #2039 would introduce a $pipestatus variable, which would allow you to pick after the fact. I don't think "always" returning 0 is awful, by any means. It's better than "basically always" returning non-zero. But I think adding that extra behavior of "failing" when the loop is never entered adds an extra bit of information that is quite hard to retrieve otherwise. Alternatively, it'd be possible to introduce |
This needs to be in the documentation for |
Done in 5cc92ff. |
Thank you @zanchey |
I'm sorry I missed this until now. "If the loop executes once always evaluate to true" is not the right behavior and we're seeing the fallout. We should just match POSIX here: "The exit status of the while loop shall be the exit status of the last compound-list-2 executed, or zero if none was executed". Basically the condition gets swallowed, but the condition of the statements inside the loop are visible. This is how fish's if statements behave. Rather than back this out I'm going to just implement the POSIX behavior. |
A while loop now evaluates to the last executed command in the body, or zero if the loop body is empty. This matches POSIX semantics. Add a bunch of tricky tests. See #4982
A while loop now evaluates to the last executed command in the body, or zero if the loop body is empty. This matches POSIX semantics. Add a bunch of tricky tests. See #4982
I'm not sure the current exit code for
while
when the loop evaluation condition returns non-zero makes sense. I understand that it passes through the value returned by the condition executable, but I'm not sure that a non-zero exit code accurately reflects the intent of the code, nor is particularly useful.This loop can terminate with either a zero or non-zero exit code. But it's equal to the following, which can only terminate with a zero exit code:
Now if the condition failed to run (instead of ran and exited with a non-zero exit code), it would make sense for
while
to return non-zero:Here, it would make sense for
$status
to evaluate to non-zero after the loop.My problem is with a script or function that executes in a loop, an explicit
return/exit 0
is needed to "override" the misleading nonzero exit code after the loop, which shouldn't (imho) ever be necessary unless a failure was detected and is being explicitly ignored.The text was updated successfully, but these errors were encountered: