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

cd ~- fails if $OLDPWD is undefined #1457

Open
krader1961 opened this issue Jan 16, 2020 · 1 comment
Open

cd ~- fails if $OLDPWD is undefined #1457

krader1961 opened this issue Jan 16, 2020 · 1 comment
Assignees
Labels

Comments

@krader1961
Copy link
Contributor

While removing problematic uses of getconf LIBPATH I noticed the src/cmd/ksh93/tests/exit.sh unit test contains these lines that I added almost two years ago to get the cd ~- test at the end of that unit test to pass:

# This would be gratuitous since our CWD should be $TEST_DIR but the `cd ~-` below requires we do
# this for it to succeed.
cd $TEST_DIR || { err_exit "cd $TEST_DIR failed"; exit 1; }

That workaround is needed on every platform other than macOS. This includes both the current version of ksh and ksh93u+. Which includes OpenIndiana (a Solaris clone), FreeBSD, OpenBSD, and several flavors of Linux. All you have to do is start a new shell and type cd ~-. On every platform other than macOS you get an error such as this (from ksh93u+ on OpenIndiana):

/bin/ksh: cd: ~-: [No such file or directory]

This is because OLDPWD is not defined by a new shell on most platforms. For example, on OpenIndiana:

$ /bin/ksh
KSH PROMPT:1: echo $OLDPWD

KSH PROMPT:2:

On MacOS:

$ /bin/ksh
KSH PROMPT:1: echo $OLDPWD
/Users/krader
KSH PROMPT:2:

Note that this behavior is true for both the last stable, ksh93u+, release and the current git master branch. This "just works" on macOS, but no other platform I have access to, because on macOS OLDPWD (at least for my shell environment) is exported and thus is imported by a new ksh instance. Presumably the old test framework implicitly did a cd in the context of the unit test prior to executing the body of the unit test. Thus making the final cd ~- "valid".

Explain to me why these two commands produce different failure modes on every system I have access to other than macOS (where OLDPWD is exported):

$ cd -
/bin/ksh: cd: no OLDPWD
$ cd ~-
/bin/ksh: cd: ~-: bad directory

It seems to me that cd ~- should be no-op if no prior cd has been executed.

P.S., bash also exhibits the same behavior. If OLDPWD is in the environment when a bash shells starts it is usable by cd ~-. If not you get a failure. And a google search suggests this is, more or less, expected behavior that is undefined by the POSIX shell specification. "More or less" because there seems to be some ambiguity regarding the "correct" behavior.

@krader1961 krader1961 added the RFC label Jan 16, 2020
@krader1961 krader1961 self-assigned this Jan 16, 2020
@jghub
Copy link

jghub commented Jan 18, 2020

you ask why cd - an cd ~- produce "different failure modes".

answer: because these are two different commands. read the manpage....

NOTE: the error messages you report are not those reported by ksh93u+ (or of ksh2020, for that matter). what exactly is /bin/ksh in your test?

regarding cd - the manpage says:

"If arg is - the directory is changed to the previous directory. "

so this requires that there is a previous directory (which implies that OLDPWD is set). so the
"no OLDPWD" you see reflects this fact (but it should report "bad directory" if it is ksh93...). cd - changes to OLDPWD or fails if the latter is unset. easy...

further you say "It seems to me that cd ~- should be no-op if no prior cd has been executed".

No, it should not. as all ksh-like shells agree (bash, mksh) to follow ksh93.

why do you not simply read the ksh manpage and look up tilde substitution (i.e. expansion)? you should make that a regular custom: read the manpage (multiple times, ideally) instead of jumping to random conclusions and speculation...

consider this (on OSX, say...):

ksh -c  'cd ~-'   # → ksh: cd: ~-: [No such file or directory]
mkdir '~-'
ksh -c 'cd ~-; pwd'   # executes the cd w/o error and  exits
rmdir '~-'   # provided you don't regularly have such a dir ...

this is exactly what should happen.

why? because ksh first does the tilde expansion in the specified way. this leads to no change of the string value ~- since OLDPWD is NEVER yet in existence after a vanilla shell start. but as with other tilde expansions (say cd ~nonexistentusername) if the tilde expansion fails the string is simply used unmodified in what follows.

so then ksh tries to cd to the directory named verbatim ~-. which might or might not exist (depending on how misguided the user is in his choices of dir names...). no problem at all.

bottom line: you are perceiving a non-existent problem/misbehaviour here. very obviously should cd ~- NOT be a no-op if the tilde expansion does not succeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants