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 ?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
Method 2
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.
Method 3
-
cdis a builtin ofbash.TABcompletion is a controlled by bash options, you can find various completion script in/usr/share/bash-completion/bash_completionand/etc/bash_completion.d.cd‘s completion method is defined in the former one. Ascdonly works on directory, it’s natural to only list available directory. - Everything is file in linux.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0