Expand description
Defining declaration utilities
This module contains the Glossary
trait, which is used by the parser to
determine whether a command name is a declaration utility. It also provides
two implementations of the Glossary
trait: EmptyGlossary
and
PosixGlossary
.
§What are declaration utilities?
A declaration utility is a type of command that causes its argument words to be expanded in a manner slightly different from other commands. Usually, command word expansion includes field splitting and pathname expansion. For declaration utilities, however, those expansions are not performed on the arguments that have a form of variable assignments.
Generally, a simple command consists of assignments, redirections, and command
words. The shell syntax allows the redirections to be placed anywhere in the
command, but the assignments must come before the command words. An assignment
token has the form name=value
, the first token that does not match this
form is considered the command name, and the rest are arguments regardless of
whether they match the form. For example, in the command a=1 b=2 echo c=3
,
a=1
and b=2
are assignments, echo
is the command name, and c=3
is an
argument.
All assignments and command words are expanded when the command is executed, but the expansions are different. The expansions of assignments are performed in a way that does not include field splitting and pathname expansion. This ensures that the values of the assignments are not split or expanded into multiple fields. The expansions of command words, on the other hand, are performed in a way that includes field splitting and pathname expansion, which may expand a single word into multiple fields.
The assignments specified in a simple command are performed by the shell
before the utility specified by the command name is invoked. However, some
utilities perform their own assignments based on their arguments. For such
a utility, the tokens that specify the assigned variable names and values
are given as arguments to the utility as in the command export a=1 b=2
.
By default, such arguments are expanded in the same way as usual command words, which means that the assignments are subject to field splitting and pathname expansion even though they are effectively assignments. To prevent this, the shell recognizes certain command names as declaration utilities and expands their arguments differently. The shell does not perform field splitting and pathname expansion on the arguments of declaration utilities that have the form of variable assignments.
§Example
POSIX requires the export
utility to be recognized as a declaration
utility. In the command v='1 b=2'; export a=$v
, the word a=$v
is not
subject to field splitting because export
is a declaration utility, so the
expanded word a=1 b=2
is passed to export
as an argument, so export
assigns the value 1 b=2
to the variable a
. If export
were not a
declaration utility, the word a=$v
would be subject to field splitting,
and the expanded word a=1 b=2
would be split into two fields a=1
and
b=2
, so export
would assign the value 1
to the variable a
and the
value 2
to the variable b
.
§Which command names are declaration utilities?
The POSIX standard specifies that the following command names are declaration utilities:
export
andreadonly
are declaration utilities.command
is neutral; it delegates to the next command word to determine whether it is a declaration utility.
It is unspecified whether other command names are declaration utilities.
The syntax parser in this crate uses the Glossary
trait to determine
whether a command name is a declaration utility. The parser calls its
is_declaration_utility
method when it encounters a command name, and
changes how the following arguments are parsed based on the result.
This module provides two implementations of the Glossary
trait:
PosixGlossary
recognizes the declaration utilities defined by POSIX (and no others). This is the default glossary used by the parser.EmptyGlossary
recognizes no command name as a declaration utility. The parse result does not conform to POSIX when this glossary is used.
You can implement the Glossary
trait for your own glossary if you want to
recognize additional command names as declaration utilities. (In yash-rs,
the yash-env
crate provides a shell environment that implements Glossary
based on the built-ins defined in the environment.)
The glossary can be set to the parser with Config::declaration_utilities
.
§Parser behavior
When the parser recognizes a command name as a declaration utility,
command words that follow the command name are tested for the form of
variable assignments. If a word is a variable assignment, it is parsed as
such: the word is split into a variable name and a value, and tilde expansions
are parsed with the parse_tilde_everywhere_after
method in the value part.
The result word is marked with ExpansionMode::Single
in
SimpleCommand::words
to indicate that the word is not subject to field
splitting and pathname expansion. If a word is not a variable assignment, it
is parsed as a normal command word with parse_tilde_front
and marked with
ExpansionMode::Multiple
.
The shell is expected to change the expansion behavior of the words based on
the ExpansionMode
of the words. In yash-rs, the semantics is implemented
in the yash-semantics
crate.
Structs§
- Empty
Glossary - Empty glossary that does not recognize any command name as a declaration utility
- Posix
Glossary - Glossary that recognizes declaration utilities defined by POSIX
Traits§
- Glossary
- Interface used by the parser to tell if a command name is a declaration utility