Shell is a program that lets you to run other programs in the terminal.
Shell allows you to pass command line arguments, set environment variables and redirect the program's stardard input / output / error. It allows you to chain programs, such that output from one program is redirected as input to another program. It also allows you to run the programs in the background. Basically, a shell allows you to easily orchestrate programs in the terminal.
When people say “run this command in a terminal” they usually mean running the command in a terminal shell. Any program (like vim) can theoretically run in the terminal on its own, without being started by a shell. But – it is the shell that allows you to type in vim file.txt and hit enter to run vim. The shell is the one that parses that and says “Aha, the user wants to run the program /usr/bin/vim and pass file.txt as the only argument”.
The most popular shell in GNU/Linux is Bash shell.
Adjacent articles:
When you open an interactive shell, you are given a command line. You run commands by typing them in the command line and hitting Enter. Command line arguments are given after the command, separated by any number of whitespaces (either spaces or tabs).
The part at the beginning is called a 'prompt'. It usually lists your user, hostname, and current working directory. In this case, user is 'root', hostname is 'localhost', and current working directory is '~' i.e. home directory of root user (which is /root). These are enclosed withing '[' and ']' characters just for decoration. The last character '#' separates the prompt from the command you're typing. Usually, the separator # indicates the user is root (as is the case here), while $ indicates the user is a regular user.
[root@localhost ~]#
The shell offers environment variables for the information that's displayed in the prompt: $USER for user, $HOSTNAME for hostname, and $PWD for current working directory. The prompt itself is defined by $PS1 variable which stands for 'Prompt String 1'. You can inspect these you can use the echo or printf commands:
[root@localhost ~]# echo $USER root [root@localhost ~]# echo $HOSTNAME localhost [root@localhost ~]# echo $PWD /root [root@localhost ~]# echo $PS1 [\u@\h \W]\$
The four basic shell commands listed in this section are cd, ls, echo, and cat. These are your legs, eyes, mouth, and ears, while you navigate the filesystem forest.
The cd command stands for “Change directory”. It's used to change the current working directory a.k.a. $PWD. You supply where you want to go with the argument e.g. cd /usr/bin. The cd command always expects a single argument. If your path has a space for example, you will have to enclose the path in quotation marks like cd "/home/user/directory with space". If you don't supply any arguments it will put you in $HOME directory. Many shells support cd - which undoes the movement in case you go somewhere you didn't want by mistake.
The cd command doesn't print anything upon success. This follows the Unix philosophy of “no news is good news” – meaning if there is no feedback then everything went fine. If you try to navigate to a non-existing directory like cd /fdsa/fdsa/fdsa then you'll likely get some feedback that the path doesn't exist.
[root@localhost ~]# cd /usr/bin
The ls command stands for “List”. It's used to list files in a directory. Commonly, you use it without arguments in order to list files in $PWD (i.e. the current working directory). Some common arguments are la -a, and la -l.
The ls -a option stands for “all” . It will include hidden files, which are just files which start with a dot, like .hidden. There is no special way to “hide” files in Unix filesystems like there is on Windows, so a convention was a established to just treat files that start with a dot as “hidden”. Configuration files in your $HOME directory often start with a dot. This is why configuration files are also commonly called “dotfiles”.
The ls -l option stands for “long”. It will include a detailed table that lists files line by line, including permissions, owner, group, size (in bytes), modification date, file name, …
To provide both -a and -l at the same time, you commonly slug them together like ls -la. There is really no difference between ls -l -a or ls -la.
[root@localhost ~]# ls / bin boot dev etc home lib lib64 mnt opt proc root run sbin srv sys tmp usr var [root@ivan-darwin /]# ls -la / total 20 drwxr-xr-x 1 root root 142 Jan 31 21:31 . drwxr-xr-x 1 root root 142 Jan 31 21:31 .. lrwxrwxrwx 1 root root 7 Oct 12 18:21 bin -> usr/bin drwxr-xr-x 6 root root 4096 Jan 1 1970 boot drwxr-xr-x 23 root root 4480 Feb 9 12:39 dev drwxr-xr-x 1 root root 3100 Feb 8 00:38 etc drwxr-xr-x 1 root root 58 Feb 1 00:19 home lrwxrwxrwx 1 root root 7 Oct 12 18:21 lib -> usr/lib lrwxrwxrwx 1 root root 7 Oct 12 18:21 lib64 -> usr/lib drwxr-xr-x 1 root root 0 Oct 12 18:21 mnt drwxr-xr-x 1 root root 184 Feb 1 01:11 opt dr-xr-xr-x 446 root root 0 Feb 9 09:11 proc drwx------ 1 root root 70 Jan 31 23:03 root drwxr-xr-x 30 root root 760 Feb 9 14:22 run lrwxrwxrwx 1 root root 7 Oct 12 18:21 sbin -> usr/bin drwxr-x--- 1 root root 2 Jan 31 21:40 .snapshots drwxr-xr-x 1 root root 14 Jan 31 21:30 srv dr-xr-xr-x 13 root root 0 Feb 9 13:13 sys drwxrwxrwt 17 root root 400 Feb 9 14:15 tmp drwxr-xr-x 1 root root 80 Feb 4 15:13 usr drwxr-xr-x 1 root root 116 Feb 4 15:30 var
The echo command is named after the echo phenomenon. The command just echoes back to you whatever you say. The utility of the command is that shell commn
[root@localhost ~]# echo $HOME /root [root@localhost ~]# echo Hello World Hello World
// Compile: gcc main.c -o main // Execute: ./main #include <stdio.h> int main(int argc, char *argv[]) { printf("argc = %d\n", argc); for (int i = 0; i < argc; i++) { printf("argv[i] = %s\n", argv[i]); } }
Some commands are internal, while most commands are external.
Internal commands are part of the shell itself. These are commands like cd, pushd, popd, jobs, fg, bg, ulimit, shopt. They affect the shell in some way e.g. the current working directory.
External commands are actual programs. These are commands like ls, cat, grep, sed, awk. When you run external commands the shell looks at the $PATH variable. Usually /bin, /usr/bin, ~/.local/bin.
In practice, there is little to no difference between internal and external commands. However internal commands don't usually have their own manpage. E.g. there is no man cd. The manual for internal commands is usually given in the man page of the shell e.g. man bash for Bash shell. External commands are independent programs and thus usually come with their own man pages (sometimes even multiple man pages!)
It “run commands”. All commands in ~/.bashrc are run whenever the shell starts.