In the linux world they can all look the same from the point of view of the user at the keyboard. The differences are in how they interact with each other.
The shell is the program which actually processes commands and returns output. Most shells also manage foreground and background processes, command history and command line editing. These features (and many more) are standard in bash
, the most common shell in modern linux systems.
A terminal refers to a wrapper program which runs a shell. Decades ago, this was a physical device consisting of little more than a monitor and keyboard. As unix/linux systems added better multiprocessing and windowing systems, this terminal concept was abstracted into software. Now you have programs such as Gnome Terminal which launches a window in a Gnome windowing environment which will run a shell into which you can enter commands.
The console is a special sort of terminal. Historically, the console was a single keyboard and monitor plugged into a dedicated serial console port on a computer used for direct communication at a low level with the operating system. Modern linux systems provide virtual consoles. These are accessed through key combinations (e.g. Alt+F1 or Ctrl+Alt+F1; the function key numbers different consoles) which are handled at low levels of the linux operating system -- this means that there is no special service which needs to be installed and configured to run. Interacting with the console is also done using a shell program.
The most common problem caused by misuse of shell startup files is that if you define environment variables in .bashrc
as opposed to .profile
, they are not defined in applications that are not launched from a shell in a terminal but rather from a GUI menu.
Defining environment variables from .bashrc
is generally not a good idea, but that's primarily because it's generally useless as the variables should already have been set at login time. It can cause a problem in practice if you (or an application) have deliberately changed the value of a variable (e.g. PATH
) in a program and you launch a shell from that program and expect the setting to have remained the same.
You can avoid the problem of environment variables being reset by defining a “sentinel” value, and not defining anything if the sentinel value is set:
if [ -z "$JMLANE_PROFILE_READ" ]; then
export ...
export JMLANE_PROFILE_READ=1
fi
Another problem caused by terminals starting login shells is that there are things that should only be done once when you log in, for example starting a password agent (e.g. ssh-agent
), or initiating a session (e.g. running startx
in certain circumstances). The sentinel variable avoids these issues.
A shell inside a terminal is always interactive. As long as you source .bashrc
from .bash_profile
when the shell is interactive, you don't need to worry about the terminal starting a login shell.
An additional wart of bash's startup file handling is that .bashrc
is read by non-interactive shells invoked by rshd or sshd. For example, when you do rsync somefile host.example.com:
, if your login shell on host.example.com
is bash, you can use .bashrc
there to set the path to include rsync
. You can tell you're in this situation because .bashrc
is read from a non-interactive shell.
## .bashrc
if [[ $- != *i* ]]; then
# either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
fi
Best Answer
A "shell" is any software that provides an interface to an operating system. For instance, explorer.exe is the default shell in Windows (though alternatives exist), and on OS X Finder provides much of the same functionality. On Linux/*nix, the shell could be part of the desktop environment (like Gnome or KDE), or can be a separate software component sitting on top of it (like Unity or Cinnamon).
The above examples are all graphical shells that use a combination of windows, menus, icons and other such elements to provide a graphical user interface (GUI) that can be interacted with using the mouse cursor. However, in the context of software like Bash, or writing scripts, "shell" is usually taken to mean a command-line interpreter, which performs largely the same duties as a graphical shell, except is entirely text-based.
Bash is a specific example of a command-line shell, and is probably one of the most well-known ones, being the default in many Linux distributions as well as OS X. It was designed as a replacement for the Bourne shell (Bash stands for "Bourne again shell"), one of the first Unix shells.
Examples of command-line shells on Windows include cmd.exe (aka Command Prompt) and PowerShell.