3

According to the Bash manual page the -e option of cd leads to an unsuccessful return status after a successful directory change.

If the -e option is supplied with -P and the current working directory cannot be successfully determined after a successful directory change, cd will return an unsuccessful status.

$ cd
$ mkdir -p test/a/b
$ cd test/a/b
$ rmdir ../b ../../a
$ cd -Pe ..; echo $?
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
1

Why is the above returning 1? How could cd -Pe .. possibly have made a successful directory change if the current as well as the parent directories do not exist anymore?

Also, if I want cd to return an unsuccessful return status each and every time it cannot change to the desired directory, what are the situations where I have to add -Pe? From what I understand it is only necessary if . or .. are used in the argument for cd.

1

2 Answers 2

3

How could cd -Pe .. possibly have made a successful directory change if the current as well as the parent directories do not exist anymore?

Because they still exist, as long as your shell (or some other process) is holding them open, or as their current directory. That's similar to how files exist until the final user has closed them, though with directories it's less useful since you can't have files in them (the directory must be empty when unlinked).

Even without -e, cd complains, but the directory change still goes through as you saw. Here, we can tell the directories apart from the permissions, not that it's still any use:

/tmp$ mkdir -p test/a/b
/tmp$ chmod 0700 test/a/b; chmod 0770 test/a
/tmp$ cd test/a/b
/tmp/test/a/b$ rmdir ../b ../../a
/tmp/test/a/b$ ls -ld .
drwx------ 0 user group 0 Mar  7 18:51 ./         # This is 'b'
/tmp/test/a/b$ cd -P ..
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
$ ls -ld .
drwxrwx--- 0 user group 0 Mar  7 18:51 ./         # this is 'a'
$ touch foo
touch: cannot touch 'foo': No such file or directory

I can't think of another way to get the working directory changed to a directory whose full path could not be determined. It's possible to cd into a directory where you don't have read access to the intervening directories. But even in that case, you'd know the path you took, either directly or by manually parsing all symlinks in the way.

And at least on Linux, getcwd() tells the path to the current directory, even if the process couldn't read the intervening directory names itself. Though the man page does mention chroots and mount namespaces as possible methods of a process being in a directory it can't access by name.

2

1 as an exit code indicates failure, not success. So cd -Pe .. is correctly indicating that it couldn’t determine the current directory after changing.

As far as I can tell, you’re right about when -Pe is necessary. In other cases, for example if you have a broken symlink to a deleted directory, cd will fail with an error message and an exit code of 1 without -Pe.

See Examples of options to bash cd, eg: cd -Pe@ $directory for more on this...

1
  • As I am understanding the quote from the manpage is that it's about the case where cd successfully changes directory but can't determine its current working directory afterwards. In this situation it would return 1 to indicate failure. Because it returned 1 in my example this must mean that it changed directory successfully (but couldn't determine its cwd afterwards). But how could it successfully change to a directory which does not exist anymore?
    – user279450
    Commented Mar 7, 2018 at 16:53

You must log in to answer this question.