8

I have a folder named ~kernel-ppa inside ~/Downloads.

aditya@aditya-desktop:~$ cd Downloads/
aditya@aditya-desktop:~/Downloads$ ls
~kernel-ppa

Now when I type cd ~k and press Tab for automatic expansion, the shell expands it to cd ~kernoops/ instead of cd ~kernel-ppa/ although the folder with same starting characters is already present.

For automatic expansion to work, I need to escape it with \. Thus using cd \~k and pressing Tab correctly expands it to cd \~kernel-ppa/. Even using cd \ and pressing Tab does the trick.

Why is it so and why do I need to escape? Moreover, what am I escaping since even ~ is not required for automatic expansion?

If I go with the flow and run cd ~kernoops/ and press Enter, the terminal status changes to //:

aditya@aditya-desktop:~/Downloads$ cd ~kernoops/
aditya@aditya-desktop://$ pwd
//
aditya@aditya-desktop://$ ls
bin   cdrom  etc   initrd.img  lost+found  mnt  proc  run   srv  tmp  var
boot  dev    home  lib         media       opt  root  sbin  sys  usr  vmlinuz
aditya@aditya-desktop://$ 

This looks like the / directory, but pwd says it is //. What exactly is it?

5
  • @RaduRădeanu Neither, it's "/home/aditya/Downloads/~kernel-ppa" Apr 2, 2014 at 13:36
  • First, "cd ~kernoops/" is taking you to "cd /home/kernoops/" which doesn't exist. Instead, you get "cd //" which is another way of writing "cd /" - it's the root directory of the root filesystem, which does look odd. Apr 2, 2014 at 13:39
  • As for why the single escape "\\" works, take a look at your folder with tree or with ls and you'll notice that happens to be the first sub-folder. Apr 2, 2014 at 13:43
  • @ElliottFrisch: I just noticed that since ~kernel-ppa is the sole folder inside it; if I just run cd and press tab, it expands to cd \~kernel-ppa/. I don't need to escape as well!
    – Aditya
    Apr 2, 2014 at 13:51
  • Yes. Also, if you keep pressing TAB you'll cycle through other available completions. Apr 2, 2014 at 13:53

2 Answers 2

10

As you know, ~ expands to your home directory. But what you seem to have missed is that ~john expands to the home directory of the user named "john".

Check your /etc/passwd file:

% grep ker /etc/passwd
kernoops:x:107:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false

It has a "system user" named kernoops (for internal bug reporting reasons). So when you type cd ~kTab the shell gives preference(1) to user name expansion before local directories expansion, and you have cd ~kernoops. Now it results that user "kernoops" home dir is /, so it cds to it.

In my shell, zsh, I have no double slash(2):

[:/] % cd ~kernoops/ 
[:/] % pwd
/
[:/] % cd //
[:/] % pwd
/

As an aside, this directory name is not well thought. It will need triple care in scripts and whatever. The only worst idea I can think is embedding a tab in it...


Footnotes:

(1) In zsh, even if I have a directory named ~xdir and no user starting with x; doing cd ~xTab does not expand and not quoting the ~ gives error:

[:~/tmp/x] %  mkdir \~xdir
[:~/tmp/x] % ls
~xdir
[:~/tmp/x] % cd ~xdir  
zsh: no such user or named directory: xdir
[:~/tmp/x] 1 % 

(2) I seem to remember that posix made an exception for the initial // in a path --- it should be maintained because some old unix variant (I used the apollos with Domain/OS that had that) used //machine-name/... to seamless access other machines' filesystem in the local network (security was not invented yet). So probably bash is right here. If you do cd /// you will have the normal / in both shell, though.

Yes, found on unix.se!

1
  • 1
    Another well-known legacy OS uses double-slash notation like that, but its slashes are typically written backwards and I'm not certain whether it accepts forward slashes for accessing network-remote filesystems like that. ;-) Apr 2, 2014 at 20:40
7

The tilde character (~) has a special meaning in the shell. When it is seen in any command, it is expanded to the name of your home directory. Doing cd ~ or cd /home/aditya is the same, it ends up in your home directory.

By putting a backslash character (\) in front of the tilde, you tell the shell to not do the expansion of the following special character (this is what is called shell escape). By doing cd \~ you ask the shell to move to a directory called ~ that would be located under the directory you are doing the command. So doing cd \~kernel-ppa will change you to the directory called ~kernel-ppa, which is the normal behaviour.

EDITED: more on ~

If you write a username of your system after the ~, you are moved to the home directory of that user. Doing a Tab expansion after cd ~ will expand to usernames existing on your system. If do Tab completion after cd ~k, it expands to ~kernoops because there is user named kernoops in the system user, with a home directory of /. As the expansion of cd ~k results into cd ~kernoops/ with a trailing slash and the home directory beeing /, you are moved to //. But this is strictly the same as / as someothers already said earlier.

1
  • Thanks for the answer. The combination of yours and @Rmano's answers clears the confusion completely :)
    – Aditya
    Apr 2, 2014 at 14:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .