This chapter defines the syntax of shell commands as a parsing expression grammar.

The set of terminals of the grammar is the set of characters that can be handled on the environment in which the shell is run (a.k.a. execution character set), with the exception that the set does not contain the null character ('\0').

Below is a list of nonterminals of the grammar with corresponding parsing expressions. The list does not include rules for parsing contents and ends of here documents. In the POSIXly-correct mode, the grammar varies from the list below to disable non-POSIX functionalities.

CompleteCommand

Sequence EOF

Sequence

N* List*

List

Pipeline ((&& / ||) N* Pipeline)* ListSeparator

Pipeline

Bang? Command (| N* Command)*

Command

CompoundCommand Redirection* /
!R FunctionDefinition /
!R SimpleCommand

CompoundCommand

Subshell /
Grouping /
IfCommand /
ForCommand /
WhileCommand /
CaseCommand /
FunctionCommand

Subshell

( Sequence ) S*

Grouping

LeftBrace Sequence RightBrace

IfCommand

If Sequence Then Sequence (Elif Sequence Then Sequence)* (Else Sequence)? Fi

ForCommand

For Name S* Separator? (In Word* Separator)? Do Sequence Done

WhileCommand

(While / Until) Sequence Do Sequence Done

CaseCommand

Case Word N* In N* CaseItem* Esac

CaseItem

!Esac (( S*)? Word (| S* Word)* ) Sequence (;; / &Esac)

FunctionCommand

Function Word (( S* ))? N* CompoundCommand Redirection*

FunctionDefinition

Name S* ( S* ) N* CompoundCommand Redirection*

SimpleCommand

&(Word / Redirection) (Assignment / Redirection)* (Word / Redirection)*

Assignment

Name = Word /
Name =( N* (Word N*)* )

Name

![[:digit:]] [[:alnum:] _]+

PortableName

![0-9] [0-9 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+

Word

(WordElement / !SpecialChar .)+ S*

WordElement

\ . /
' (!' .)* ' /
" QuoteElement* " /
Parameter /
Arithmetic /
CommandSubstitution

QuoteElement

\ ([$`"\] / NL) /
Parameter /
Arithmetic /
CommandSubstitution /
![`"\] .

Parameter

$ [@*#?-$! [:digit:]] /
$ PortableName /
$ ParameterBody

ParameterBody

{ ParameterNumber? (ParameterName / ParameterBody / Parameter) ParameterIndex? ParameterMatch? }

ParameterNumber

# ![+=:/%] !([-?#] })

ParameterName

[@*#?-$!] /
[[:alnum:] _]+

ParameterIndex

[ ParameterIndexWord (, ParameterIndexWord)? ]

ParameterIndexWord

(WordElement / !["'],] .)+

ParameterMatch

:? [-+=?] ParameterMatchWord /
(# / ## / % / %%) ParameterMatchWord /
(:/ / / [#%/]?) ParameterMatchWordNoSlash (/ ParameterMatchWord)?

ParameterMatchWord

(WordElement / !["'}] .)*

ParameterMatchWordNoSlash

(WordElement / !["'/}] .)*

Arithmetic

$(( ArithmeticBody* ))

ArithmeticBody

\ . /
Parameter /
Arithmetic /
CommandSubstitution /
( ArithmeticBody ) /
![`()] .

CommandSubstitution

$( Sequence ) /
` CommandSubstitutionBody* `

CommandSubstitutionBody

\ [$`\] /
!` .

Redirection

RedirectionFD RedirectionOperator S* Word /
RedirectionFD <( Sequence ) /
RedirectionFD >( Sequence )

RedirectionFD

[[:digit:]]*

RedirectionOperator

< / <> / > / >| / >> / >>| / <& / >& / << / <<- / <<<

ListSeparator

Separator /
& N* /
&) /
&;;

Separator

; N* /
N+ /
EOF

N

S* NL

S

[[:blank:]] /
Comment

Comment

# (!NL .)*

R

Bang / LeftBrace / RightBrace / Case / Do / Done / Elif / Else / Esac / Fi / For / If / In / Then / Until / While

Bang

! D

LeftBrace

{ D

RightBrace

} D

Case

case D

Do

do D

Done

done D

Elif

elif D

Else

else D

Esac

esac D

Fi

fi D

For

for D

Function

function D

If

if D

In

in D

Then

then D

Until

until D

While

while D

D

!Word S*

SpecialChar

[|&;<>()`\"' [:blank:]] / NL

NL

<newline>

EOF

!.