5

The Bourne Again shell manual says, of cd dir:

[…] each directory name in CDPATH is searched for dir. […] If dir begins with a slash (/), then CDPATH is not used.

The Z shell manual says, of cd arg:

Otherwise, if arg begins with a slash, attempt to change to the directory given by arg.

If arg does not begin with a slash, the behaviour depends on whether the current directory . occurs in the list of directories contained in the shell parameter cdpath. […] If . occurs in cdpath, then cdpath is searched strictly in order so that . is only tried at the appropriate point.

The POSIX Ordinary shell manual says, of CDPATH:

Works the same way as PATH for those directories not beginning with / in cd commands.

The Debian Almquist shell manual says, of cd:

If […] the shell variable CDPATH is set and the directory name does not begin with a slash, then the directories listed in CDPATH will be searched for the specified directory.

The '93 Korn shell manual says, of cd arg:

If arg begins with a / then the search path is not used. Otherwise, each directory in the path is searched for arg.

The MirBSD Korn shell manual says, of CDPATH:

It works the same way as PATH for those directories not beginning with / in cd commands.

With the single exception of the '93 Korn shell, none of these are actually the case:

% export CDPATH=/tmp:
% mkdir wibble /tmp/wibble
% ksh93 -c 'cd ./wibble'
/tmp/wibble
% dash -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% bash -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% mksh -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% lksh -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% posh -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% zsh -c 'cd ./wibble ; pwd'
/home/JdeBP/wibble
% 

/tmp/./wibble exists and is a directory, but only the '93 Korn shell is searching CDPATH and finding it. The rest are not.

Why not?

  • Note that in the case of ksh93, CDPATH=/tmp ksh -c 'cd ..' does not cd to /tmp/.. (while it does for go to /tmp/. for cd .) – Stéphane Chazelas Jan 19 '18 at 9:34
  • The CDPATH feature comes either from the Bourne shell (already in SVR1 in 1983, not in the initial version in V7), or possibly ksh (which is from around the same time (1983), but I never found much information on it before ksh86), and already then cd . or .. would not consider CDPATH, still not documented (except with comments in the code as seen in ksh86 source code). – Stéphane Chazelas Jan 19 '18 at 9:41
  • Note that the behaviour is documented in tcsh – Stéphane Chazelas Jan 19 '18 at 9:41
  • ksh86 code – Stéphane Chazelas Jan 19 '18 at 9:46
6

Because the manuals are wrong.

The '93 Korn shell is wrong, too.

The 1997 Single Unix Specification says:

If the directory operand does not begin with a slash (/) character, and the first component is not dot or dot-dot, cd will search for directory relative to each directory named in the CDPATH variable, in the order listed.

The 2016 Single Unix Specification says the same in a different, and slightly redundant, way:

3. If the directory operand begins with a <slash> character, set curpath to the operand and proceed to step 7.

4. If the first component of the directory operand is dot or dot-dot, proceed to step 6.

[…]

6. Set curpath to the directory operand.

None of the manuals mention the part about . and .., but that is what every shell apart from the '93 Korn shell is actually doing, despite what their manuals say:

% export CDPATH=/tmp:
% lksh -c 'cd wibble'
/tmp/wibble
% dash -c 'cd wibble'
/tmp/wibble
% posh -c 'cd wibble'
/tmp/wibble
% bash -c 'cd wibble'
/tmp/wibble
% mksh -c 'cd wibble'
/tmp/wibble
% zsh -c 'cd wibble ; pwd'
/tmp/wibble
% 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.