the 'cd //' conundrum

SysAdminTechnology



Not a new subject, but still interesting.

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


Trackbacks

Trackback specific URI for this entry

Comments

Display comments as Linear | Threaded

No comments

Add Comment

Submitted comments will be subject to moderation before being displayed.

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Gravatar, Twitter, Pavatar, Identica author images supported.
Markdown format allowed