1

Weird unix thing: 'cd //'

 3 years ago
source link: https://jvns.ca/blog/2017/02/08/weird-unix-things-cd/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Weird unix thing: 'cd //'



Today my friend Mat told me an interesting trivia fact about cd!

Look at this interaction, where we try to cd /tmp, cd //tmp, and cd ///tmp, in bash and in fish.

bork@kiwi/> bash
bork@kiwi:/$ cd //tmp
bork@kiwi://tmp$ echo $PWD
//tmp
bork@kiwi:/tmp$ cd ///tmp
bork@kiwi:/tmp$ echo $PWD
/tmp
bork@kiwi://tmp$ fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
bork@kiwi:/tmp> cd //tmp
bork@kiwi:/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.

bork@kiwi:~$ 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: -
bork@kiwi:~$ 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

The specification for cd is here

Here’s the relevant section

An implementation may further simplify curpath by removing any trailing <slash> characters that are not also leading <slash> characters, replacing multiple non-leading consecutive <slash> characters with a single <slash>, and replacing three or more leading <slash> characters with a single <slash>. If, as a result of this canonicalization, the curpath variable is null, no further steps shall be taken.

So! 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? Mat pointed out there is a “Rationale” section in this spec, but it does not really explained.

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 stack overflow said that this is related to the double slash in URLs (“http://“…) but didn’t provide a citation. Is that true?

If I find out, I will update this blog post with an answer.

update 1: there seems to be a pretty good answer in this stack overflow question


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK