Closed daviduhden closed 2 months ago
oBSD's ksh
is pdksh
, not ksh88
or ksh93
(which each have different ideas about scopes).
A good discussion by Stéphane Chazelas is here.
This issue appears to stem from the OpenBSD global initialization script for KornShell located in /etc/ksh.kshrc. The script contains a command that is not supported by ksh93. Specifically, the command
local
. In order to fix this problem you have to replace it bytypeset
.
Yes, that's right. Adding local
is definitely on our to-do list, but since it is expected to have dynamic scoping which ksh93 doesn't support, this is a puzzle we haven't solved yet (it does static scoping only, see Q28 here).
In the meantime, you can solve the problem by editing src/cmd/ksh93/SHOPT.sh
and changing SHOPT SYSRC=
to SHOPT SYSRC=0
. That will stop it from detecting /etc/ksh.kshrc at compile time and disable the behaviour of loading it at startup.
Of course that's only a partial solution. The user's ~/.kshrc
may be incompatible as well.
Maybe a better solution would be: on systems where the default ksh on $PATH
is not ksh93 at build time, compile ksh to use variant names like /etc/ksh93.kshrc
and ~/.ksh93rc
by default. What do you think?
I don't agree. You are special-casing real ksh
behavior in favor of things that call themselves ksh
but aren't. The place for that behavior is in the shell script itself, not in the shell. Not that you'd ever get oBSD to go along with that, since pdksh
is in their base.
What's next, /etc/profile
and ~/.profile
? That way just leads to the mess that is bash
.
things that call themselves
ksh
but aren't
That ship sailed more than three decades ago. If AT&T hadn't insisted on such an outdated and destructive proprietary mindset from the get go, neither pdksh nor bash would ever have existed, and the community would have stepped in to fix the mess that AT&T was making of ksh.
It's AT&T that screwed up by making ksh93 incompatible with ksh88, so it's not for us now to take the arrogant position that pdksh isn't a “real” ksh. It's a 99.9% accurate clone of the ksh88 of the days (even emulating some of its bugs), which is very impressive given that the source code was a closely guarded corporate secret then.
The place for that behavior is in the shell script itself, not in the shell. Not that you'd ever get oBSD to go along with that, since
pdksh
is in their base.
Exactly. Rigid adherence to principles is often a good thing, but I'm not convinced of that in this particular case. This is not the first time this issue annoys people. I've run into it myself as well. Plus, I'm the one who is going to have to deal with the reports that are going to keep coming in if something isn't done about this.
It's not as if there isn't a precedent, anyway. It's common for the shell binary to be called ksh93
on systems where ksh
might be pdksh or mksh. Why should the rc scripts not follow suit?
Which reminds me of the fact that ksh is already detecting what it's called at runtime to decide whether or not to default to POSIX mode (when invoked as sh
). So should be easy to add a little code for it to adapt the rc script names at runtime. If it's called ksh93
, it should look for matching ksh93rc script names, otherwise nothing changes.
What's next,
/etc/profile
and~/.profile
?
profile
scripts are specified by POSIX and are expected to work on all the POSIX shells by limiting themselves to sh
(1) commands. I can promise you that nothing is going to change there.
That way just leads to the mess that is
bash
.
Compared to the incredible mess that the AT&T folks left for us to tidy up, bash (for all its flaws) is a paragon of correctness and reliability. Chet Ramey and the FSF simply did a better job than AT&T did.
Even after fixing well over 1000 AT&T bugs, as long as we have not managed to fix bugs/design flaws like #771, we have no business calling any other shell a mess, full stop.
By the way, I do appreciate you contributing your opinion, even if I don't end up agreeing with it. In fact, it was useful as it caused me to think this whole thing through more deeply.
I don't think there's a problem with ksh
adapting to the name of the binary at run-time, but I do feel 100% there's a problem with the behavior being a compile-time decision. Your comment in https://github.com/ksh93/ksh/issues/776#issuecomment-2267592548 sounded like the latter.
(BTW I will never stop thinking that the collection of how rc files work in bash
is completely broken.)
I don't think there's a problem with
ksh
adapting to the name of the binary at run-time, but I do feel 100% there's a problem with the behavior being a compile-time decision. Your comment in #776 (comment) sounded like the latter.
Yeah, that was my original idea. I agree with you that a runtime decision is better.
(BTW I will never stop thinking that the collection of how rc files work in bash is completely broken.)
I never claimed bash is flawless :)
On systems where the default ksh on
$PATH
is not ksh93 at build time, compile ksh to use variant names like/etc/ksh93.kshrc
and~/.ksh93rc
by default.
What would need to be modified to implement this? I would like to propose a patch in the OpenBSD port to fix this problem. It might be better if you could solve this problem in the original project by adding conditionals for operating systems that use another KornShell implementation by default, such as OpenBSD, NetBSD and MirBSD.
@daviduhden, here is a patch for you to test. Please let me know how it works for you.
As discussed above with @posguy99, it makes the decision at runtime, based on whether ksh is invoked as ksh93
. If so, it looks for /etc/ksh93.kshrc
and ~/.ksh93rc
instead of the names without the 93
. Since our ksh is generally installed as ksh93
on systems that have another ksh as the default, this should meet your needs.
Here is a patch for you to test. Please let me know how it works for you.
I have tested the patch on OpenBSD 7.6-beta, and ksh93u+m now functions perfectly. I had to make some adjustments to the diff for init.c as it did not apply to version 1.0.10. The patches have already been proposed for the OpenBSD port along with an update to version 1.0.10. Thank you for your attention. It is rare to see a developer work so diligently to resolve issues that arise with the software they maintain.
OpenBSD port maintainer here.
I do agree that we should probably patch out sourcing of /etc/ksh.kshrc
(if need be, even just locally in the OpenBSD port), but changing the default user initialisation file to $HOME/.ksh93rc
is way over the top and will break existing user setups not only on OpenBSD, but most Linux distributions. One should generally be able to maintain a .kshrc
that works with different versions of ksh
.
So I think the simplest solution would be to just make the value of e_sysrc[]
configurable at build time.
Thanks for the feedback. I will give this some more thought.
Oh, and … does the Mamfile
really check for existence of /etc/ksh.kshrc
or /etc/bash.bashrc
on the build machine and base its decision of whether to include the sysrc feature on the existence of one of those files? That's just wrong. I think SHOPT_SYSRC
should always be included. It’s also documented this way.
Oh, and … does the
Mamfile
really check for existence of/etc/ksh.kshrc
or/etc/bash.bashrc
on the build machine and base its decision of whether to include the sysrc feature on the existence of one of those files? That's just wrong. I thinkSHOPT_SYSRC
should always be included.
ksh93 has always worked this way by default, even in the AT&T days. You can edit src/cmd/ksh93/SHOPT.sh
and set SYSRC
to 1 to always enable /etc/ksh.kshrc or to 0 to always disable it. The way to do that for a port would be through a local patch.
It’s also documented this way.
It isn't. src/cmd/ksh93/README
quite clearly documents the current practice. In SHOPT.sh itself, it's mentioned that an empty value means probe.
Then it is broken since AT&T days. A README
in the source code is not user-facing documentation, and the man page does not give any clear indication if ksh
supports the sysrc feature on a given system.
The check for /etc/ksh.kshrc
may have made some semblance of sense "back in the day" -- nowadays it just leads to confusion and unexpected behaviour for both package maintainers and users. You’ll even end up with a different Korn Shell depending on if bash
is installed or not on the build machine.
This is exactly one of those behaviours this project should fix by providing some sensible default.
I concede the point. The SHOPT_SYSRC probe is broken.
As for the rest of this issue, it seems like someone is going to be unhappy no matter what I decide, so I'm deciding to change as little as necessary to achieve sanity.
The SHOPT_SYSRC probe is deleted from the Mamfile and SHOPT_SYSRC is now enabled by default. On systems such as NetBSD and OpenBSD, where /etc/ksh.kshrc is incompatible by default, users building ksh93 will have to either change its value to 0 to disable loading /etc/ksh.kshrc at startup, or edit /etc/ksh.kshrc to make it compatible with ksh93.
I will add a paragraph to README.md to make users (and packagers) aware of this.
I encountered a serious problem after changing the root user's shell to ksh93 1.0.8 on OpenBSD 7.5 using the chpass(1) command.
When executing basic commands such as
cd
orexit
, the following error messages are displayed:For
cd
:-ksh93: wcd[93]: _ignore_: line 89: local: not found
For
exit
:-ksh93: wsu[97]: _ignore_: line 89: local: not found
Additionally, when executing the
pwd
command, the following error is displayed:-ksh93: pwd: cannot determine present working directory [No such file or directory]
While the actions for
cd
andexit
are still executed despite the error, thepwd
command becomes completely unusable.This issue appears to stem from the OpenBSD global initialization script for KornShell located in /etc/ksh.kshrc. The script contains a command that is not supported by ksh93. Specifically, the command
local
. In order to fix this problem you have to replace it bytypeset
.