Look at this interaction, where we try to cd /tmp, cd //tmp, and cd ///tmp, in bash and in fish:
m3ta@dragon/> bash m3ta@dragon:/$ cd //tmp m3ta@dragon://tmp$ echo $PWD //tmp m3ta@dragon:/tmp$ cd ///tmp m3ta@dragon:/tmp$ echo $PWD /tmp m3ta@dragon://tmp$ fish Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish m3ta@dragon:/tmp> cd //tmp m3ta@dragon:/tmp> echo $PWD /tmp
What is //tmp? What is happening? Why is cd ///tmp different from cd //tmp?
Here’s what we know so far:
are / and // the same file? Yes.
We can check this with stat.
They both have the same inode number (256) so they are the same file.
m3ta@dragon:~$ stat / File: '/' Size: 244 Blocks: 0 IO Block: 4096 directory Device: 16h/22d Inode: 256 Links: 1 Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2017-02-08 23:13:55.647187990 -0500 Modify: 2017-01-10 13:01:30.987733887 -0500 Change: 2017-01-10 13:01:30.987733887 -0500 Birth: - m3ta@dragon:~$ stat // File: '//' Size: 244 Blocks: 0 IO Block: 4096 directory Device: 16h/22d Inode: 256 Links: 1 Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2017-02-08 23:13:55.647187990 -0500 Modify: 2017-01-10 13:01:30.987733887 -0500 Change: 2017-01-10 13:01:30.987733887 -0500 Birth: -
Cool. But what is //? Why doesn’t bash just correct it to /?
The specification for cd is here
Here’s the relevant section:
An implementation may further simplify curpath by removing any trailing characters that are not also leading characters, replacing multiple non-leading consecutive characters with a single , and replacing three or more leading characters with a single . If, as a result of this canonicalization, the curpath variable is null, no further steps shall be taken.
We can replace “three or more leading / characters with a single slash”.
That does not say anything about what to do when there are 2 / characters though, which presumably is why cd //tmp leaves you at //tmp.
Why is this the specification?
In another specification, it says:
A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner
So you can define //tmp to mean whatever you want? Like it could be different than /tmp?
Why? Somebody on stackoverflow said that this is related to the double slash in URLs (“http://“…) but didn’t provide a citation.
There seems to be a pretty good answer in this stackoverflow question