ksh-community / ksh

ksh93 maintenance and development
Eclipse Public License 1.0
26 stars 11 forks source link

HOME=/dest cd does not honour the HOME environment #19

Closed Earnestly closed 1 year ago

Earnestly commented 1 year ago

The builtin cd does not appear to check its environment for HOME when determining where to change the working directory when given no arguments.

# HOME=/bin cd; pwd
/root # Should be /bin

This otherwise works in every shell-including bourne-and is specified by POSIX:

  1. If no directory operand is given and the HOME environment variable is set to a non-empty value, the cd utility shall behave as if the directory named in the HOME environment variable was specified as the directory operand.
jghub commented 1 year ago

I believe the following excerpt from the ksh manpage is relevant:

The environment for any simple-command or function may be augmented by prefixing
it with one or more variable assignments.  A variable assignment argument is a word of
the form identifier=value.  Thus:

              TERM=450 cmd args
 and
              (export TERM; TERM=450; cmd args)

are equivalent (as far as the above execution of cmd is concerned except for special
built-in commands listed below - those that are  preceded with a dagger).

and cd does not belong to the group of excepted special built-ins. so the above-stated equivalence to the sub-shell analogue holds. so the cd command in your example is a no-op. if you change your example to

HOME=/bin; cd

(split your single command into two) it of course will work as expected.

Earnestly commented 1 year ago

The suggested solution is incorrect as you have now modified the shell environment. The manpage you have shown is correct but doesn't conform to how the cd builti-in functions, precisely because it is not a Special Built-in.

I don't quite know how to read the code but it appears to read the HOME as a shell variable rather than explicitly fetching it from the environment, how this differs in this context I don't know.

The cd in my example as per POSIX is to treat the value of HOME as the operand, and proceed as usual. This should entail both CDPATH lookup and following OLDPWD semantics when the operand is -; however many shells seem to bypass these two aspects, which is likely also incorrect in the context of POSIX. If ksh doesn't really care about POSIX then it can clearly do whatever it likes here, I don't use ksh much but found this aspect of its cd surprising.

jghub commented 1 year ago

The suggested solution is incorrect as you have now modified the shell environment. The manpage you have shown is correct but doesn't conform to how the cd builti-in functions, precisely because it is not a Special Built-in.

I don't think so since it happens in a subshell. e.g. executing

(foo=bar; print ":$foo:"); print :$foo:

does not know of foo in the second print. the environment is not modified outside of the subshell. and cd is a special builtin just not belonging to the subgroup of special builtins referred to in the manpage at that point ("preceded by a dagger").

... The cd in my example as per POSIX is to treat the value of HOME as the operand, and proceed as usual. This should entail both CDPATH lookup and following OLDPWD semantics when the operand is -; however many shells seem to bypass these two aspects, which is likely also incorrect in the context of POSIX. If ksh doesn't really care about POSIX then it can clearly do whatever it likes here, I don't use ksh much but found this aspect of its cd surprising.

I can't judge that (what behaviour is POSIX compliant behaviour here and what is not). ksh sure cares for compliance, though.

and maybe you raise that question again here

https://github.com/ksh93

where there a people more knowledgable than me in these matters. and if it were a bug (which I presently do not presume it is since behaviour in total concordance with ksh manpage) they probably would fix it :).

McDutchie commented 1 year ago

Yes, this should work, and it's a bug that it doesn't. cd is a regular built-in command, so the preceding assignment to HOME should be in effect while cd is executed.

Confirmed in ksh 93u+ 2012-08-01 and in current ksh 93u+m. I'll file a bug there.

McDutchie commented 1 year ago

Fixed in https://github.com/ksh93/ksh/commit/993238dab2cbccf4bf569c02bfaa3eb5fbf21a65