Skip to content
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

exec: Don't exit after error in interactive shells #803

Merged
merged 2 commits into from
Dec 18, 2024

Conversation

JohnoKing
Copy link

As of POSIX.1-2024, interactive shells are not allowed to exit when exec fails to run a command*. This commit amends ksh's exec implementation to comply with this requirement (in path_exec()).

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
As of POSIX.1-2024, interactive shells are not allowed to exit when
exec(1) fails to run a command[*]. This commit amends ksh's
implementation to comply with this requirement (in path_exec()).

[*]: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_21
@McDutchie
Copy link

McDutchie commented Dec 15, 2024

Thanks for the PR!

One problem:

$ exec nonexistent >/dev/null 2>&1

...and now you have a basically unusable shell: no prompt is displayed and nothing you type is echoed. You're operating blind.

This behaviour is actually specified by POSIX 2024: "If the exec command fails and the shell does not exit, any redirections associated with the exec command that were successfully made shall take effect in the current shell execution environment."

But I think that's worse than it was before; at least when you lost your shell you could log back in or reopen the terminal window, and you didn't have to operate blind. So I do wonder if this highly undesirable side effect in the case of a nonexistent comment was actually intended by the resolution of Austin Group bug 1157.

@posguy99
Copy link

posguy99 commented Dec 15, 2024

Why does the spec say "If the exec command fails and the shell does not exit..."? What's the point of the and?

bash (even the old macOS bash) hangs as you describe. mksh, oksh, and dash (and ksh) exit back to the parent. yash does something different:

mwilson@mbp-m2 ~ 2$ echo $YASH_VERSION
2.57
mwilson@mbp-m2 ~ 2$ exec nonexistent >/dev/null 2>&1
mwilson@mbp-m2 ~ 127 2$ 

It failed the exec, but it didn't exit back to the parent, and the redirects aren't in effect.

@McDutchie
Copy link

McDutchie commented Dec 18, 2024

Why does the spec say "If the exec command fails and the shell does not exit..."? What's the point of the and?

The point is that the shell, in the new 2024 spec, shall not exit on failure to execute the command if it is interactive. In other words, if it's non-interactive, it still exits.

None of this affects scripts, by the way, or even subshells of interactive shells. Nothing changes there compared to the old spec.

bash (even the old macOS bash) hangs as you describe.

It doesn't hang though, it just doesn't show any output. You can blindly type something (e.g. exit) and it will be executed.

Still, I think this is clearly broken, it's not something I am willing to subject users to, and I will file an Austin Group bug about it. When a user does 'exec cmd >file', they expect the shell to be replaced by cmd with the redirection to file in effect. But if cmd cannot be executed and the shell is not replaced, then it makes no sense for the redirection to persist, because it was intended for cmd only.

mksh, oksh, and dash (and ksh) exit back to the parent.

They are still acting according to the pre-2024 spec.

yash does something different:

mwilson@mbp-m2 ~ 2$ echo $YASH_VERSION
2.57
mwilson@mbp-m2 ~ 2$ exec nonexistent >/dev/null 2>&1
mwilson@mbp-m2 ~ 127 2$ 

It failed the exec, but it didn't exit back to the parent, and the redirects aren't in effect.

That is sane behaviour, and it's how I would like ksh to act.

@McDutchie
Copy link

I'll merge this first, then fix the usability issue separately.

@McDutchie McDutchie merged commit 53937b9 into ksh93:dev Dec 18, 2024
McDutchie pushed a commit that referenced this pull request Dec 18, 2024
As of POSIX.1-2024, interactive shells are not allowed to exit when
exec(1) fails to run a command[*]. This commit amends ksh's
implementation to comply with this requirement (in path_exec()).

[*]: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_21
@McDutchie
Copy link

@JohnoKing JohnoKing deleted the conform-to-posix-exec branch December 19, 2024 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants