What is the difference between . (or ..) and ~ character with respect to how they are treated by the bash? If i use ~ character, bash expands it to absolute path but if is use . (or ..) bash does not expand it to absolute path?

My pwd is home directory. Now, when i run the command: ls '.' (or ls .) it shows me the contents of the pwd but if i run the command: ls '~', it gives the error that the file or directory does not exists. This means ~ is expanded by shell before passing it to the ls command but . is not. Is . not a special character? When is . (or ..) treated as special character and expanded by the shell?


2 Answers 2


The dot . isn't a special character in the shell. All the properties of the . and .. directory links are just about the filesystem structure, the shell has nothing to do with it. Note that even there, it's not the character, but those two specific names. foo.txt, .bar and ... are regular file names, even if the ones starting with a dot are treated specially by globs and ls.

On the other hand, ~ is a regular character for the filesystem, but in the shell Tilde Expansion treats it specially. So an unquoted ~ at the start of a word gets expanded to the current user's home directory, and ~foo gets expanded to the home directory of user foo.

(Of course the shell does know about what . and .. are, in that running cd .. from /tmp doesn't make the current working directory show as /tmp/.., but as /. Also, unlike letters and _, the dot isn't valid in variable names, like e.g. ,, % and - aren't.)


~ as stand-alone - that is unquoted - is interpreted by the shell as being the home directory. When you quote it, that interpretation stops, so it is not like ordinary variables.

. and .. are references in the file system.

So, if you try to use . in a C program (so without the shell) that would work, as in:

#include <stdio.h>

int main(void) {
  DIR *d;
  struct dirent *dir;
  d = opendir(".");  /*<---------------See the . for current dir */
  if (d) {
    while ((dir = readdir(d)) != NULL) {
      printf("%s\n", dir->d_name);

whereas if you try that with ~, (d = opendir("~");) that won't work.

You must log in to answer this question.

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