Bash follows the POSIX Shell Command Language Introduction, but adds several extra steps to support the extra features of Bash. The shell does a number of distinct chores, in this order:
-c command option, or from stdin
(standard input).
Note if the first line of a file of shell commands starts with the characters
"#!", the results are unspecified (because some other
utility is then responsible for reading the file).
| & ; < > ( ) $ ` \ " ' <space> <tab> <newline>
The following characters need to be quoted under certain circumstances:
* ? [ # ˜ = %
The various quoting mechanisms are the escape character (back-slash) which
quotes the following character and is sometimes called escaping,
single-quotes(e.g. 'x') which quotes all enclosed
characters,
and double-quotes ("x") which quotes all enclosed
characters except '$', '\',
'`', and '\x' only when x
is a meta-character).
Note '!' (history expansion) acts weirdly in bash inside
of double quotes from the command line but not in a shell script (which
has no history mechanism enabled).
Another part of tokenizing is line joining.
If the current line ends with "\newline" these two
characters skipped and the next line is joined to the current one.
Comment removal is the last part of tokenizing the input.
@' within double-quotes.
The expansions are done in this order:
~username" to the
absolute pathname of the home directory for
username.
If the word is a bare tilde ("~") it expands to the
absolute pathname of the current user's home directory.)
$")
with the results of a lookup in the environment.
Note if no such parameter is found this expands to nothing.
also note that words of the form "$(stuff)"
are treated specially by Bash.)
$(embedded command line)" and
"`embedded command line`" by recursively
processing and running the embedded command, and replacing
the embedded command line with the standard output of the command.)
$((expression))".)
IFS as a
delimiter and splits the results of parameter expansion and command
substitution into fields (words).
If the value of IFS is <space>,
<tab>, and <newline>
(collectively called whitespace) or if it is unset,
then any whitespace at the beginning or end of the input is skipped
and any sequence of whitespace characters within the input delimits
a field.
For example, the input:
<newline><space><tab>foo<tab><tab>bar<space>
yields two fields, foo and bar.
If the value of IFS is null then no field splitting
is performed.
-f is in effect).
1 to
n, and the name of the command (or the name of
the script) as the positional parameter numbered 0.
The environment for the new command is initialized from the shell's
current environment, modified by any I/O redirections and variable
assignments made.
$?"
to that value.
Note the history mechanism works at some point (via the
readline library), but is not part of
POSIX.
Since some characters have special meaning to readline
(such as ‘^' and ‘!') these may
appear to be meta-characters sometimes and not meta-characters
at other times.
It depends on the shell in use and its history configuration,
if readline is used, and your ~/.inputrc file which is
to configure it.
Apparently readline knows about single-quote and backslash quoting
but doesn't recognize double-quotes.