Hello, (If you don't want to read through this stuff, see the end or grep for word ``opinion''.)
I started exploring details of file handling on Linux and similar systems and wondered what ``cd ""'' will do. I was experimenting with various shells. Let's start with some non-GNU shells on one FreeBSD system. (The shell prompts were replaced with ``$'' to make the examples more readable.) ksh93: $ ksh93 --version version sh (AT&T Research) 93u+m/1.1.0-alpha+e2f62ff7/MOD 2023-12-28h $ cd "" ksh93: cd: bad directory tcsh (2 versions): $ tcsh --version tcsh 6.22.04 (Astron) 2021-04-26 (x86_64-amd-FreeBSD) options wide,nls,dl,al,kan,sm,rh,color,filec $ tcsh --version tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec $ cd "" : No such file or directory. # Another one: ksh: $ ksh --version GNU bash, verze 5.1.8(1)-release (x86_64-unknown-freebsd13.0) ~~snip~~ Whoa, It's bash! Let's try it later. zsh: [user@host]/% pwd / [user@host]/% cd "" [user@host]/% pwd / [user@host]/% cd /tmp [user@host]/tmp% cd "" [user@host]/tmp% pwd /tmp * * * And now the behavior of the Bash. I tried these versions: GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu) GNU bash, version 5.1.8(1)-release (x86_64-unknown-freebsd13.0) GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu) GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu) GNU bash, version 5.2.26(0)-release (amd64-portbld-freebsd13.2) The behavior is the same as for the zsh. It simply leaves the working directory unchanged. $ cd / $ cd "" $ echo $? 0 $ pwd / POSIX Programmer's Manual (cd(1p) manpage) says this: [9 unrelated special cases] 10. The cd utility shall then perform actions equivalent to the chdir() function called with curpath as the path argument. If these actions fail for any reason, the cd utility shall display an appropriate error message and the remainder of this step shall not be executed. [...] So, it should do the same thing a chdir(""). I interpret it as ``it shall fail if chdir("") would fail''. Let's try that: $ >a.c cat int main(){chdir("");perror("uwu");} $ gcc a.c [gcc's warnings] $ ./a.out uwu: No such file or directory (I've also checked it better. The error is really ENOENT.) So, the chdir("") call fails. Have a look at manpages. path_resolution(7) says: Empty pathname In the original UNIX, the empty pathname referred to the current directory. Nowadays POSIX decrees that an empty pathname must not be resolved successfully. Linux returns ENOENT in this case. [from Linux man-pages 6.05.01] So, the behavior of Bash corresponds to the *old* behavior of chdir(2). Why it is not the same? Let's explore: $ cd /tmp $ strace sh 2>&1 -c 'cd ""' | grep chdir chdir("/tmp") = 0 Well, the shell does some magic with the pathname before passing it finally to the chdir(2). (After examining the source code of the current bash version, it just concatenates the empty string to the working directory path in this case.) My opinion on this is that the ``cd ""'' command should fail with an error in this case. The zsh is the only POSIX-compatible or POSIX-shell-like shell that was available on machines to which I have access that exhibits this behavior. I think that the empty argument can be relatively frequently caused by substitution with some undefined variable -- it's better to warn the user than to perform actions in the wrong directory. We risk that this will break some badly written scripts. I propose to make Bash report an error when the user attempts to cd into empty string, possibly with an shopt option that allows changing behaviour of the cd back to the current one -- silently ignoring the command. Jiri Wolker.