TODO: Explain two types of representation (low-level and high-level API).
The root node of the AST tree.
{ ( SequentialList
| AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )* }
{
type: 'Program',
body: [ ( SequentialList
| AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )* ],
comments: [ Comment* ]
}
{ ( SequentialList
| AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )+ }
{
type: 'CompoundList',
cmds: [ ( SequentialList
| AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )+ ]
}
Commands that are separated by a semicolon
;
shall be executed sequentially. Read more…
command1; command2 [; command3 ] ... [;]
{ ( AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )+ }
{
type: 'SequentialList',
cmds: [ ( AsyncCommand
| AndOrList
| Not
| PipeSequence
| Command )+ ]
}
If a command is terminated by the control operator
&
, the shell shall execute the command asynchronously in a subshell. Read more…
command &
{ ( AndOrList
| Not
| PipeSequence
| Command ) }
{
type: 'AsyncCommand',
cmd: ( AndOrList
| Not
| PipeSequence
| Command )
}
An AND-OR list is a sequence of one or more pipelines separated by the operators
&&
and||
. They shall have equal precedence and shall be evaluated with left associativity. Read more…
command1 && command2 [ || command3] ...
command1 || command2 [ && command3] ...
{
( OrList
| Not
| PipeSequence
| Command ),
(
( Not
| PipeSequence
| Command )
)+
}
{
type: 'AndList',
cmds: [ ( OrList
| Not
| PipeSequence
| Command ),
(
( Not
| PipeSequence
| Command )
)+ ]
}
{
( AndList
| Not
| PipeSequence
| Command ),
(
( Not
| PipeSequence
| Command )
)+
}
{
type: 'OrList',
cmds: [ ( AndList
| Not
| PipeSequence
| Command ),
(
( Not
| PipeSequence
| Command )
)+ ]
}
! command
{ ( PipeSequence
| Command ) }
{
type: 'Not',
cmd: ( PipeSequence
| Command )
}
A pipeline is a sequence of one or more commands separated by the control operator
|
. For each command but the last, the shell shall connect the standard output of the command to the standard input of the next command as if by creating a pipe and passing the write end of the pipe as the standard output of the command and the read end of the pipe as the standard input of the next command. Read more…
command1 | command2 [| command3 ] ...
{ Command+ }
{
type: 'PipeSequence',
cmds: [ Command+ ]
}
A “simple command” is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator. Read more…
{ { ( Redirect | Assignment )* }, Word | nil, { ( Redirect | Word )* } | nil }
-
Redirections and assignments (prefix).
-
Command name. If nil, then (1) is not empty and (3) is nil.
-
Redirections and command arguments (suffix).
TODO
[modifier] varname=value ...
{
type: 'Assignments',
assignments: [ Assignment+ ],
modifier: 'export' | 'local' | 'readonly' | null
}
Execute compound-list in the current process environment. Read more…
{ compound-list ; }
{ CompoundList, { Redirect* } }
{
type: 'BraceGroup',
body: CompoundList,
redirs: [ Redirect* ]
}
Execute compound-list in a subshell environment; see Shell Execution Environment. Read more…
( compound-list )
{ CompoundList | nil, { Redirect* } }
{
type: 'Subshell',
body: CompoundList | null,
redirs: [ Redirect* ]
}
The if command shall execute a compound-list and use its exit status to determine whether to execute another compound-list. Read more…
if compound-list
then
compound-list
[elif compound-list
then
compound-list] ...
[else
compound-list]
fi
If : { { IfClause, ElifClause*, ElseClause? }, { Redirect* } }
IfClause : { CompoundList, CompoundList }
ElifClause : { CompoundList, CompoundList }
ElseClause : { CompoundList }
{
type: 'If',
clauses: [ IfClause, ElifClause*, ElseClause? ],
redirs: [ Redirect* ]
}
{
type: 'IfClause',
cond: CompoundList,
body: CompoundList
}
{
type: 'ElifClause',
cond: CompoundList,
body: CompoundList
}
{
type: 'ElseClause',
body: CompoundList
}
The for loop shall execute a sequence of commands for each member in a list of items. Read more…
for name [ in [word ... ]]
do
compound-list
done
{ Name, { Word* }, CompoundList, { Redirect* } }
-
Variable name.
-
List of items to loop over.
-
Body of the for loop.
-
Redirections.
{
type: 'For',
var: Name,
items: [ Word* ],
body: CompoundList,
redirs: [ Redirect* ]
}
The conditional construct case shall execute the compound-list corresponding to the first one of several patterns (see Pattern Matching Notation) that is matched by the string resulting from the tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal of the given word. Read more…
case word in
[(] pattern1 ) compound-list ;;
[[(] pattern[ | pattern] ... ) compound-list ;;] ...
[[(] pattern[ | pattern] ... ) compound-list]
esac
Case : { Word, { CaseItem* }, { Redirect* } }
CaseItem : { { Word+ }, CompoundList }
{
type: 'Case',
var: Name,
cases: [ CaseItem* ],
redirs: [ Redirect* ]
}
{
type: 'CaseItem',
pattern: [ Word+ ],
body: CompoundList
}
The while loop shall continuously execute one compound-list as long as another compound-list has a zero exit status. Read more…
while compound-list-1
do
compound-list-2
done
{ CompoundList, { Redirect* } }
{
type: 'While',
cond: CompoundList,
body: CompoundList,
redirs: [ Redirect* ]
}
The until loop shall continuously execute one compound-list as long as another compound-list has a non-zero exit status. Read more…
until compound-list-1
do
compound-list-2
done
{ CompoundList, { Redirect* } }
{
type: 'Until',
cond: CompoundList,
body: CompoundList,
redirs: [ Redirect* ]
}
A function is a user-defined name that is used as a simple command to call a compound command with new positional parameters. Read more…
fname ( ) compound-command [io-redirect ...]
{ Name, CompoundCommand, { Redirect* } }
{
type: 'FunctionDef',
name: Name,
body: CompoundCommand,
redirs: [ Redirect* ]
}
Redirection is used to open and close files for the current shell execution environment (see Shell Execution Environment) or for any command. Read more…
[n]redir-file-op word
{ number | nil, redir-file-op, Word }
-
File descriptor number (or nil if not specified).
-
Operator.
-
File path, or file descriptor number.
{
type: 'RedirectFile',
fd: number | null,
op: redir-file-op,
file: Word
}
redir-file-op: '<' | '<&' | '>' | '>|' | '>>' | '>&' | '<>'
The redirection operators
<<
and<<-
both allow redirection of subsequent lines read by the shell to the input of a command. The redirected lines are known as a “here-document”. Read more…
[n] <<[-] word
here-document
delimiter
{ number | nil, '<<' | '<<-', Word, HereDocContent (!), number }
-
File descriptor number (or nil if not specified).
-
Operator.
-
The delimiter word.
-
TODO
-
ID of this here-document.
{ ( string | Expansion )+ }
{
type: 'Word',
content: [ ( string | Expansion )+ ]
}
See Parameter Expansion for more information.
${[prefix-op] variable [infix-op [ word ]]}
{ prefix-op?, param-name, ( infix-op, string )? }
{
type: 'ParameterExpansion',
op_pre: prefix-op | null,
param: string,
op_in: infix-op | null,
word: string | null
}
prefix-op: '#'
infix-op: ':-' | '-' | ':=' | '=' | ':?' | '?' | ':+' | '+' | '%%' | '%' | '##' | '#' | ':' | '//' | '/'
Arithmetic expansion provides a mechanism for evaluating an arithmetic expression and substituting its value. Read more…
$((expression))
{ string }
{
type: 'ArithmeticExpansion',
text: string
}
Command substitution allows the output of a command to be substituted in place of the command name itself. Read more…
$(command)
{ CompoundList* }
{
type: 'CommandSubstitution',
cmds: [ CompoundList* ]
}