What is the difference between Terminal, Console, Shell, and Command Line?
Ubuntu – the difference between Terminal, Console, Shell, and Command Line
command lineconsoleterminology
Related Solutions
>
is used to overwrite (“clobber”) a file and >>
is used to append to a file.
Thus, when you use ps aux > file
, the output of ps aux
will be written to file
and if a file named file
was already present, its contents will be overwritten.
And if you use ps aux >> file
, the output of ps aux
will be written to file
and if the file named file
was already present, the file will now contain its previous contents and also the contents of ps aux
, written after its older contents of file
.
There's a strong difference between a builtin and a keyword, in the way Bash parses your code. Before we talk about the difference, let's list all keywords and builtins:
Builtins:
$ compgen -b
. : [ alias bg bind break
builtin caller cd command compgen complete compopt
continue declare dirs disown echo enable eval
exec exit export false fc fg getopts
hash help history jobs kill let local
logout mapfile popd printf pushd pwd read
readarray readonly return set shift shopt source
suspend test times trap true type typeset
ulimit umask unalias unset wait
Keywords:
$ compgen -k
if then else elif fi case
esac for select while until do
done in function time { }
! [[ ]] coproc
Notice that, for example [
is a builtin and that [[
is a keyword. I'll use these two to illustrate the difference below, since they are well-known operators: everybody knows them and uses them regularly (or should).
A keyword is scanned and understood by Bash very early in its parsing. This allows for example the following:
string_with_spaces='some spaces here'
if [[ -n $string_with_spaces ]]; then
echo "The string is non-empty"
fi
This works fine, and Bash will happily output
The string is non-empty
Note that I didn't quote $string_with_spaces
. Whereas the following:
string_with_spaces='some spaces here'
if [ -n $string_with_spaces ]; then
echo "The string is non-empty"
fi
shows that Bash isn't happy:
bash: [: too many arguments
Why does it work with keywords and not with builtins? because when Bash parses the code, it sees [[
which is a keyword, and understands very early that it's special. So it will look for the closing ]]
and will treat the inside in a special way. A builtin (or command) is treated as an actual command that is going to be called with arguments. In this last example, bash understands that it should run the command [
with arguments (shown one per line):
-n
some
spaces
here
]
since variable expansion, quote removal, pathname expansion and word splitting occurs. The command [
turns out to be built in the shell, so it executes it with these arguments, which results in an error, hence the complaint.
In practice, you see that this distinction allows for sophisticated behavior, that wouldn't be possible with builtins (or commands).
Still in practice, how can you possibly distinguish a builtin from a keyword? this is a fun experiment to perform:
$ a='['
$ $a -d . ]
$ echo $?
0
When Bash parses the line $a -d . ]
, it sees nothing special (i.e., no aliases, no redirections, no keywords), so it just performs variable expansion. After variable expansions, it sees:
[ -d . ]
so executes the command (builtin) [
with arguments -d
, .
and ]
, which, of course is true (this only tests whether .
is a directory).
Now look:
$ a='[['
$ $a -d . ]]
bash: [[: command not found
Oh. That's because when Bash sees this line, it sees nothing special, and hence expands all variables, and eventually sees:
[[ -d . ]]
At this time, alias expansions and keyword scanning has long been performed and is not going to be performed anymore, so Bash tries to find the command called [[
, doesn't find it, and complains.
Along the same lines:
$ '[' -d . ]
$ echo $?
0
$ '[[' -d . ]]
bash: [[: command not found
and
$ \[ -d . ]
$ echo $?
0
$ \[[ -d . ]]
bash: [[: command not found
Alias expansion is something rather special too. You've all done the following at least once:
$ alias ll='ls -l'
$ ll
.... <list of files in long format> ....
$ \ll
bash: ll: command not found
$ 'll'
bash: ll: command not found
The reasoning is the same: alias expansion occurs long before variable expansion and quote removal.
Keyword v.s. Alias
Now what do you think happens if we define an alias to be a keyword?
$ alias mytest='[['
$ mytest -d . ]]
$ echo $?
0
Oh, it works! so aliases can be used to alias keywords! nice to know.
Conclusion: builtins really behave like commands: they correspond to an action being executed with arguments that undergo direct variable expansion and word splitting and globbing. It's really just like having an external command somewhere in /bin
or /usr/bin
that is called with the arguments given after variable expansion, etc. Note that when I say it's really just like having an external command I only mean with respect to arguments, word splitting, globbing, variable expansion, etc. A builtin can modify the shell's internal state!
Keywords, on the other hand, are scanned and understood very early, and allow for sophisticated shell behavior: the shell will be able to forbid word splitting or pathname expansion, etc.
Now look at the list of builtins and keywords and try to figure out why some need to be keywords.
!
is a keyword. It seems it would be possible to mimic its behavior with a function:
not() {
if "$@"; then
return 1
else
return 0
fi
}
but this would forbid constructs like:
$ ! ! true
$ echo $?
0
(in that case, I mean not ! true
which doesn't work) or
$ ! { true; }
echo $?
1
Same for time
: it's more powerful to have it a keyword so that it can time complex compound commands and pipelines with redirections:
$ time grep '^#' ~/.bashrc | { i=0; while read -r; do printf '%4d %s\n' "$((++i))" "$REPLY"; done; } > bashrc_numbered 2>/dev/null
If time
where a mere command (even builtin), it would only see the arguments grep
, ^#
and /home/gniourf/.bashrc
, time this, and then its output would go through the remaining parts of the pipeline. But with a keyword, Bash can handle everything! it can time
the complete pipeline, including the redirections! If time
were a mere command, we couldn't do:
$ time { printf 'hello '; echo world; }
Try it:
$ \time { printf 'hello '; echo world; }
bash: syntax error near unexpected token `}'
Try to fix (?) it:
$ \time { printf 'hello '; echo world;
time: cannot run {: No such file or directory
Hopeless.
Keyword vs alias?
$ alias mytime=time
$ alias myls=ls
$ mytime myls
What do you think happens?
Really, a builtin is like a command, except that it's built in the shell, whereas a keyword is something that allows for sophisticated behavior! we can say it's part of the shell's grammar.
Related Question
- Ubuntu – What’s is the difference between “>” and “>>” in shell command
- Ubuntu – What’s the difference between shell builtin and shell keyword
- Ubuntu – What’s the difference between the TTY and the GNOME terminal
- Ubuntu – difference between these command
- Ubuntu – the difference between Ctrl-z and Ctrl-c in the terminal
- Ubuntu – the difference between “>” and “>>”
- Ubuntu – Difference between | and ||
Best Answer
Short answer:
Long answer:
Console and terminal are closely related. Originally, they meant a piece of equipment through which you could interact with a computer: in the early days of unix, that meant a teleprinter-style device resembling a typewriter, sometimes called a teletypewriter, or “tty” in shorthand. The name “terminal” came from the electronic point of view, and the name “console” from the furniture point of view. Very early in unix history, electronic keyboards and displays became the norm for terminals.
Terminal
In unix terminology, a terminal is a particular kind of device file which implements a number of additional commands (ioctls) beyond read and write. Some terminals are provided by the kernel on behalf of a hardware device, for example with the input coming from the keyboard and the output going to a text mode screen, or with the input and output transmitted over a serial line. Other terminals, sometimes called pseudo-terminals or pseudo-ttys, are provided (through a thin kernel layer) by programs called terminal emulators. Some types of terminal emulators include:
The word terminal can also have a more traditional meaning of a device through which one interacts with a computer, typically with a keyboard and display. For example an X terminal is a kind of thin client, a special-purpose computer whose only purpose is to drive a keyboard, display, mouse and occasionally other human interaction peripherals, with the actual applications running on another, more powerful computer.
Console
A console is generally a terminal in the physical sense that is by some definition the primary terminal directly connected to a machine. The console appears to the operating system as a (kernel-implemented) terminals. On some systems, such as Linux and FreeBSD, the console appears as several terminals (ttys) (special key combinations switch between these terminals); just to confuse matters, the name given to each particular terminal can be “console”, ”virtual console”, ”virtual terminal”, and other variations.
See also Why is a Virtual Terminal “virtual”, and what/why/where is the “real” Terminal?.
Command line [interface]
A command line is an interface where the user types a command (which is expressed as a sequence of characters — typically a command name followed by some parameters) and presses the Return key to execute that command.
Shell
A shell is the primary interface that users see when they log in, whose primary purpose is to start other programs. (I don't know whether the original metaphor is that the shell is the home environment for the user, or that the shell is what other programs are running in.)
In unix circles, shell has specialized to mean a command-line shell, centered around entering the name of the application one wants to start, followed by the names of files or other objects that the application should act on, and pressing the Enter key. Other types of environments (with the notable recent exception of Gnome Shell) usually don't use the word “shell”; for example, window systems involve “window managers” and “desktop environments”, not a “shell”.
There are many different unix shells. Ubuntu's default shell is Bash (like most other Linux distributions). Popular alternatives include zsh (which emphasizes power and customizability) and fish (which emphasizes simplicity).
Command-line shells include flow control constructs to combine commands. In addition to typing commands at an interactive prompt, users can write scripts. The most common shells have a common syntax based on the Bourne_shell. When discussing “shell programming”, the shell is almost always implied to be a Bourne-style shell. Some shells that are often used for scripting but lack advanced interactive features include the Korn shell (ksh) and many ash variants. Pretty much any Unix-like system has a Bourne-style shell installed as
/bin/sh
, usually ash, ksh or bash. On Ubuntu,/bin/sh
is Dash, an ash variant (chosen because it is faster and uses less memory than bash).In unix system administration, a user's shell is the program that is invoked when they log in. Normal user accounts have a command-line shell, but users with restricted access may have a restricted shell or some other specific command (e.g. for file-transfer-only accounts).
The division of labor between the terminal and the shell is not completely obvious. Here are their main tasks.
\e[D
). The shell converts control sequences into commands (e.g.\e[D
→backward-char
).M-x shell
in Emacs.foo
”, “switch the foreground color to green”, “move the cursor to the next line”, etc. The terminal acts on these instructions.Recycled from Unix & Linux