Everyone, who has been a Linux user, must have typed various commands on shell, or the so-called shell commands, knowingly or unknowingly – at least the ubiquitous command “ls”. However, have one wondered, how one gets these commands?
A command which one types on shell is broadly available from one of the following three places:
- An executable from some standard path in the file system
- A built-in of the shell, available from the shell’s binary itself
- An alias or function created by the shell
“ls” – every Linux users’ typical first command, basically comes from the “ls” executable located under /bin. And so are many more commands. All such commands come from one of the directories like /bin, /usr/bin, /sbin, etc. The complete list of such directories can be obtained from the PATH environment variable by typing:
$ echo ${PATH}
Typing this as a normal user would show the list of directories for commands available to a normal user. And typing it as a root user would show the list of directories for commands available to root user. Moreover, one could add directories to the corresponding PATH variable as well, using “export” command.
Given a command available from executable, e.g. “ls”, one may find its directory using the “which” command as follows:
$ which ls
What about the “which” command itself? Try:
$ which which
What about the “cd” command? Try:
$ which cd
And you’ll get a message saying no cd in the path. But then, cd still works, right? Just type:
$ type cd
And it would show that it is a shell built-in – the second type of the command types. And, it makes sense to be a built-in as well, as meaning of current working directory (the concept around “cd”) is relevant only with respect to a shell. What about the “type” command, itself? Any guess? Try:
$ type type
Yes, as expected, this is also a shell built-in. What about the “which” command? Try:
$ type which
And it shows, as expected, that it is an executable being picked up from a corresponding hashed directory. What about the “ls” command? Try:
$ type ls
Ouch! This is not as expected. It doesn’t show “ls” as an executable from a corresponding directory, but rather that “ls” is aliased to some string like “ls -F –color=auto” or so. Why is it so? Because the “ls” command we type, is actually an alias to the “ls” executable (with the specific colour options) – the third type of command types. And, that’s why we see coloured listing by default when we type “ls”. One can create aliases using the “alias” command, which itself is a shell built-in, as expected. And aliases override commands from the actual executables.
What if one wants to bypass the alias and directly call the executable? The command with the complete executable path, e.g. “/bin/ls”, may be invoked, or it may be backslashed, as follows:
$ \ls
Observe the non-coloured output of the original “ls” executable.
So to conclude, “type” command gives the actual type (out of the three types) for any command we type on shell. “which” command is to figure out the directory of its corresponding executable, if any. And “alias” command would list out all the aliases currently defined under the corresponding shell.
On a side note, “man” command typically provides help on the shell’s executable commands only. For a built-in command, it may just open up the man page of the shell itself. So, for specific help on built-in commands, you may use the “help” command, e.g.:
$ help cd
Parting question: Which type of command is “help”? Try out the various commands on it and have fun exploring the types of shell commands.