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.