pub trait Command {
// Required method
async fn execute(&self, env: &mut Env) -> Result;
}
Expand description
Syntactic construct that can be executed.
Required Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl Command for Command
Executes the command.
impl Command for Command
Executes the command.
After executing the command body, the execute
function runs
traps if any caught signals are pending, and
updates subshell statuses.
Source§impl Command for CompoundCommand
Executes the compound command.
impl Command for CompoundCommand
Executes the compound command.
§Grouping
A grouping is executed by running the contained list.
§Subshell
A subshell is executed by running the contained list in a separate
environment (Subshell
).
After the subshell has finished, Env::apply_errexit
is called.
§For loop
Executing a for loop starts with expanding the name
and values
. If
values
is None
, it expands to the current positional parameters. Each
field resulting from the expansion is assigned to the variable name
, and
in turn, body
is executed.
§While loop
The condition
is executed first. If its exit status is zero, the body
is
executed. The execution is repeated while the condition
exit status is
zero.
§Until loop
The until loop is executed in the same manner as the while loop except that
the loop condition is inverted: The execution continues until the
condition
exit status is zero.
§If conditional construct
The if command first executes the condition
. If its exit status is zero,
it runs the body
, and its exit status becomes that of the if command.
Otherwise, it executes the condition
of each elif-then clause until
finding a condition that returns an exit status of zero, after which it runs
the corresponding body
. If all the conditions result in a non-zero exit
status, it runs the else
clause, if any. In case the command has no else
clause, the final exit status will be zero.
§Case conditional construct
The “case” command expands the subject word and executes the body of the first item with a pattern matching the word. Each pattern is subjected to word expansion before matching.
POSIX does not specify the order in which the shell tests multiple patterns in an item. This implementation tries them in the order of appearance.
After executing the body of the matching item, the case command may process the next item depending on the continuation.
Source§impl Command for AndOrList
Executes the and-or list.
impl Command for AndOrList
Executes the and-or list.
The &&
operator first executes the left-hand-side pipeline, and if and
only if the exit status is zero, executes the right-hand-side. The ||
operator works similarly but runs the right-hand-side if and only if the
left-hand-side exit status is non-zero. The &&
and ||
operators are
left-associative and have equal precedence.
The exit status of the and-or list will be that of the last executed pipeline.
Frame::Condition
is pushed to the environment’s stack while the
execution of the pipelines except for the last.
Source§impl Command for FullCompoundCommand
Executes the compound command.
impl Command for FullCompoundCommand
Executes the compound command.
The redirections are performed, if any, before executing the command body.
Redirection errors are subject to the ErrExit
option
(Env::apply_errexit
).
Source§impl Command for FunctionDefinition
Executes the function definition command.
impl Command for FunctionDefinition
Executes the function definition command.
First, the function name is expanded. If the expansion fails, the execution ends with a non-zero exit status. Next, the environment is examined for an existing function having the same name. If there is such a function that is read-only, the execution ends with a non-zero exit status. Finally, the function definition is inserted into the environment, and the execution ends with an exit status of zero.
The ErrExit
shell option is applied on error.
Source§impl Command for Item
Executes the item.
impl Command for Item
Executes the item.
§Synchronous command
If the item’s async_flag
is None
, this function executes the and-or list
in the item.
§Asynchronous command
If the item has an async_flag
set, the and-or list is executed
asynchronously in a subshell, whose process ID is set to the job
list in the environment.
Since this function finishes before the asynchronous execution finishes, the exit status does not reflect the results of the and-or list; the exit status is always 0.
If the Monitor
option is off, the standard input of the asynchronous
and-or list is implicitly redirected to /dev/null
.
Source§impl Command for List
Executes the list.
impl Command for List
Executes the list.
The list is executed by executing each item in sequence. If any item results
in a Divert
, the remaining items are not
executed.
Source§impl Command for Pipeline
Executes the pipeline.
impl Command for Pipeline
Executes the pipeline.
§Executing commands
If this pipeline contains one command, it is executed in the current shell execution environment.
If the pipeline has more than one command, all the commands are executed concurrently. Every command is executed in a new subshell. The standard output of a command is connected to the standard input of the next command via a pipe, except for the standard output of the last command and the standard input of the first command, which are not modified.
If the pipeline has no command, it is a no-op.
§Exit status
The exit status of the pipeline is that of the last command (or zero if no
command). If the pipeline starts with an !
, the exit status is inverted:
zero becomes one, and non-zero becomes zero.
In POSIX, the expected exit status is unclear when an inverted pipeline
performs a jump as in ! return 42
. The behavior disagrees among existing
shells. This implementation does not invert the exit status when the return
value is Err(Divert::...)
.
§noexec
option
If the Exec
and Interactive
options are Off
in env.options
,
the entire execution of the pipeline is skipped. (The noexec
option is
ignored if the shell is interactive, otherwise you cannot exit the shell
in any way if the ignoreeof
option is set.)
§Stack
if self.negation
is true, Frame::Condition
is pushed to the
environment’s stack while the pipeline is executed.
Source§impl Command for SimpleCommand
Executes the simple command.
impl Command for SimpleCommand
Executes the simple command.
§Outline
The execution starts with the expansion of the command
words. Next, the command search is performed to
find an execution target named by the first
field of the expansion results. The target type defines how the
target is executed. After the execution, the ErrExit
option is applied
with Env::apply_errexit
.
§Target types and their semantics
§Absent target
If no fields resulted from the expansion, there is no target.
If the simple command has redirections and assignments, they are performed in a new subshell and the current shell environment, respectively.
If the redirections or assignments contain command substitutions, the exit status of the simple command is taken from that of the last executed command substitution. Otherwise, the exit status will be zero.
§Built-in
If the target is a built-in, the following steps are performed in the current shell environment.
First, if there are redirections, they are performed.
Next, if there are assignments, a temporary context is created to contain the assignment results. The context, as well as the assigned variables, are discarded when the execution finishes. If the target is a regular built-in, the variables are exported.
Lastly, the built-in is executed by calling its body with the remaining fields passed as arguments.
§Function
If the target is a function, redirections are performed in the same way as a regular built-in. Then, assignments are performed in a volatile variable context and exported. Next, a regular context is pushed to allow local variable assignment during the function execution. The remaining fields not used in the command search become positional parameters in the new context. After executing the function body, the contexts are popped.
If the execution results in a Divert::Return
, it is consumed, and its
associated exit status, if any, is set as the exit status of the simple
command.
§External utility
If the target is an external utility, a subshell is created. Redirections
and assignments, if any, are performed in the subshell. The assigned
variables are exported. The subshell calls the
execve
function to invoke the external utility
with all the fields passed as arguments.
If execve
fails with an ENOEXEC
error, it is re-called with the current
executable file so that the restarted shell executes the external utility as
a shell script.
§Target not found
If the command search could not find a valid target, the execution proceeds
in the same manner as an external utility except that it does not call
execve
and performs error handling as if it failed with ENOENT
.
§Redirections
Redirections are performed in the order of appearance. The file descriptors modified by the redirections are restored after the target has finished except for external utilities executed in a subshell.
§Assignments
Assignments are performed in the order of appearance. For each assignment, the value is expanded and assigned to the variable.
§Errors
§Expansion errors
If there is an error during the expansion, the execution aborts with a non-zero exit status after printing an error message to the standard error.
Expansion errors may also occur when expanding an assignment value or a redirection operand.
§Redirection errors
Any error happening in redirections causes the execution to abort with a non-zero exit status after printing an error message to the standard error.
§Assignment errors
If an assignment tries to overwrite a read-only variable, the execution aborts with a non-zero exit status after printing an error message to the standard error.
§External utility invocation failure
If the external utility could not be called, the subshell exits after printing an error message to the standard error.
§Portability
POSIX does not define the exit status when the execve
system call fails
for a reason other than ENOEXEC
. In this implementation, the exit status
is 127 for ENOENT
and ENOTDIR
and 126 for others.
POSIX leaves many aspects of the simple command execution unspecified. The detail semantics may differ in other shell implementations.