I wanted to change current directory into shell script into directory, containing specific regular file. I found that following trick works in mksh
and busybox sh
:
path=/path/to/regular/file
cd $path/..
but not in GNU Bash:
bash: cd: /path/to/regular/file/..: Not a directory
Is this trick not posix-compatible, or Bash is too pedantic?
Latest edition of the standard doesn't allow that. POSIX.1-2017 cd
spec. says that if the pathname component preceding dot-dot is not a directory, cd
shall consider that an error.
From cd
§ DESCRIPTION - step 8.b:
b. For each dot-dot component, if there is a preceding component and
it is neither root nor dot-dot, then:
i. If the preceding component does not refer (in the context of
pathname resolution with symbolic links followed) to a
directory, then the cd utility shall display an appropriate
error message and no further steps shall be taken.
When cd
is invoked with -P
option, this step is omitted; but then chdir()
fails if one of the pathname components names an existing file that is neither a directory nor a symbolic link to a directory.
Besides, permitting that trick also allows inconsistent behavior in cd
. For example, when run in a directory containing a regular file named bar
, and a directory named foo
containing another directory named bar
, the following two commands do different things in a shell where cd
ignores non-directory components preceding a dot-dot, despite that CDPATH
contains the empty string (i.e. the current working directory) in both cases.
CDPATH= cd bar/..
CDPATH=:foo cd bar/..
Below transcripts visualize the difference between non-conforming and conforming implementations clearly.
$ tree -F
.
├── bar
└── foo/
└── bar/
2 directories, 1 file
$ ash
$ CDPATH= cd bar/..
$ pwd
/home/oguz
$ CDPATH=:foo cd bar/..
/home/oguz/foo
$ bash
$ CDPATH= cd bar/..
bash: cd: bar/..: Not a directory
$ CDPATH=:foo cd bar/..
/home/oguz/foo
bosh, gwsh, ksh93u+m, and yash are other actively maintained shells that implement the same behavior as bash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With