14

In Linux, every single entity is considered as FILE. If I do vim <cd-Name> then, vim will open the directory content into it's editor, because, it do not differentiate between file and directories.

But today while working, I encountered a thing, which I am curious to know about.

I planned to open a file from nested directory

vim a/b/c/d/file

But instead of vim, I typed

 cd a/b/c/d/

and hit the TAB twice, but command was showing only the available directory of the "d" directory rather files.

Don't the cd command honour "everything is a file"? Or am I missing something ?

chaos
  • 48,171
SHW
  • 14,786
  • 14
  • 66
  • 101
  • 2
    vim differentiates between files and directories (it even says ""." is a directory" when you open one); it just thinks you might find it useful to use it as a tree browser. It's not related to the "everything is a file" mantra. – Michael Homer Aug 26 '15 at 06:11

3 Answers3

41

The "Everything is a file" phrase defines the architecture of the operating system. It means that everything in the system from processes, files, directories, sockets, pipes, ... is represented by a file descriptor abstracted over the virtual filesystem layer in the kernel. The virtual filesytem is an interface provided by the kernel. Hence the phrase was corrected to say "Everything is a file descriptor". Linus Torvalds himself corrected it again a bit more precisely: "Everything is a stream of bytes".

However, every "file" has also an owner and permissions you may know from regular files and directories. Therefore classic Unix tools like cat, ls, ps, ... can query all those "files" and it's not needed to invent other special mechanisms, than just the plain old tools, which all use the read() system call. For example in Microsofts OS-family there are multiple different read() system calls (I heard about 15) for any file types and every of them is a bit different. When everything is a file, then you don't need that.

To your question: Of course there are different file types. In linux there are 7 file types. The directory is one of them. But, the utilities can distinguish them from each other. For example, the complete function of the cd command (when you press TAB) only lists directories, because the stat() system call (see man 2 stat) returns a struct with a field called st_mode. The POSIX standard defines what that field can contain:

       S_ISREG(m)  is it a regular file?
       S_ISDIR(m)  directory?
       S_ISCHR(m)  character device?
       S_ISBLK(m)  block device?
       S_ISFIFO(m) FIFO (named pipe)?
       S_ISLNK(m)  symbolic link? (Not in POSIX.1-1996.)
       S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

The cd command completion function just displays "files" where the S_ISDIR flag is set.

chaos
  • 48,171
7

Your shell is smart enough to know that cd will not work with file parameters. So when you hit tab it only shows things in that directory that will work with cd.

sashang
  • 736
1
  1. cd is a builtin of bash. TAB completion is a controlled by bash options, you can find various completion script in /usr/share/bash-completion/bash_completion and /etc/bash_completion.d. cd's completion method is defined in the former one. As cd only works on directory, it's natural to only list available directory.

  2. Everything is file in linux.

  • Everything is a file unless it's a directory. I remember doing od -x . to find out what funny characters someone had put into a filename. Try this today. You can use hexdump if od is not on your system. – ott-- Aug 26 '15 at 20:55
  • please refer to @chaos answer. – Chris Tsui Aug 27 '15 at 03:14