Module std.process
Process execution.
run and run_argv execute a command to completion and capture its
output. start launches a Command (never through a shell) and returns a
Child whose piped stdio are ordinary Stream<bytes> and Sink<bytes>
values. Command.output(CaptureLimits { timeout, max_output_bytes })
captures both output streams with a runtime limit and a shared byte budget.
start and Command.output inherit the parent's environment and working
directory. start_with_options and Command.output_with_options accept a
SpawnOptions snapshot: Environment.Inherit(bindings) overlays inherited
variables, while Environment.Clear(bindings) passes only explicit
bindings, including none. Neither operation changes process-global state.
Both spawn paths use the same owned Child and native lifecycle.
A Child owns its process until it is reaped. wait suspends the calling
task and holds no thread while the child runs: it parks on the I/O reactor
(a pidfd on Linux, a kqueue process filter on FreeBSD and macOS) or, on
Windows, on the system thread pool's wait for the process handle. Any
number of tasks may wait on children at once. The reaped status is kept,
so a second wait returns it again and a later terminate or kill does
nothing. Dropping a Child that is still running kills and reaps it.
A child's stdout and stderr streams are select sources on every native
host. A losing selection leaves its data available for the next receive.
Windows retains at most 64 KiB of completed output per pipe; pending reads
use overlapped I/O and release their buffers after cancellation completes.
Examples
import std.encoding.utf8;
import std.process;
fn main() {
let output = process.run_argv("printf", ["<%s>", "hello world"]).expect("printf runs");
println(output.stdout);
var command = process.command("cat", []);
command.stdin = process.Stdio.Piped;
command.stdout = process.Stdio.Piped;
let child = process.start(command).expect("cat starts");
let input = child.stdin().expect("stdin is piped");
let echoed = child.stdout().expect("stdout is piped");
input.send("ping".to_bytes()).expect("cat reads");
input.finish();
for chunk in echoed {
println(utf8.decode_lossy(chunk));
}
println(f"{child.wait():?}");
}
import std.process;
fn main() {
let options = process.SpawnOptions {
environment: .Clear([process.EnvVar { name: "LANG", value: "C" }]),
cwd: .None,
};
let command = process.command("tool", ["--version"]);
let output = command.output_with_options(
process.CaptureLimits { timeout: 5s, max_output_bytes: 4096 },
options,
).expect("tool runs with only the approved binding");
println(output.stdout);
}
Contents
- fn run
- fn run_argv
- fn command
- fn inherited_options
- fn start_with_options
- fn start
- enum Stdio
- struct Command
- struct EnvVar
- enum Environment
- struct SpawnOptions
- struct CaptureLimits
- enum ExitStatus
- struct CommandOutput
- enum ProcessError
- struct Child
- inherent methods
Functions
Function run
pub fn run(command: string) -> Result<CommandOutput, ProcessError>
Run a shell command and capture its status and output. Waiting for output or exit suspends the caller; cancellation reaps the child.
Function run_argv
pub fn run_argv(command: string, args: Vec<string>) -> Result<CommandOutput, ProcessError>
Run a program without the shell and capture its status and output. Both output streams drain concurrently while the caller is suspended.
Function command
pub fn command(program: string, args: Vec<string>) -> Command
A Command for program with args and every stream inherited.
Function inherited_options
pub fn inherited_options() -> SpawnOptions
Options matching the defaults of start and Command.output.
Function start_with_options
pub fn start_with_options(command: Command, options: SpawnOptions) -> Result<Child, ProcessError>
Launch with per-child environment bindings and an optional working directory.
Bindings are applied in order; the last binding for a name wins. Name
comparison follows the host (case-insensitive on Windows). Empty names,
names containing = or NUL, values containing NUL, and empty or NUL-containing
working directories return InvalidArguments without launching a child.
Other operating-system failures return LaunchFailed. Diagnostics never
include environment values.
Use an absolute program path with cwd: resolving a relative program path
against a changed working directory is platform-dependent. Program lookup
and any environment variables added by the child follow the host's rules;
clearing inheritance is not a sandbox.
Function start
pub fn start(command: Command) -> Result<Child, ProcessError>
Launch command without waiting. A program that cannot be launched is
Err(ProcessError.LaunchFailed).
Types
Enum Stdio
Where a child's standard stream goes.
Variants
InheritShare this program's stream.
NullConnect the stream to the null device.
PipedConnect the stream to a pipe the parent takes once from the
Child.
Struct Command
A program, its arguments and its stdio. The arguments reach the program exactly as given; no shell interprets them.
Fields
Struct EnvVar
An explicit child environment binding. Empty values are allowed.
Fields
Enum Environment
The environment of a new child, without changing the parent's environment.
Variants
Struct SpawnOptions
Optional per-child configuration for start_with_options and
Command.output_with_options. Existing Command literals stay unchanged.
Fields
- environment: Environment
- cwd: Option<string>
Noneinherits the parent's working directory. A relative directory resolves from the parent's working directory.
Struct CaptureLimits
Limits for Command.output.
Fields
- timeout: duration
A positive runtime limit, including draining output and waiting for exit.
- max_output_bytes: i64
The maximum retained raw stdout and stderr bytes together; zero permits no output. A chunk that would exceed this limit is rejected before append.
Enum ExitStatus
How a process ended.
Variants
Exited(i64)The process exited with this code.
Signalled(i64)A signal with this number ended the process (Unix only).
Struct CommandOutput
Captured output from a completed command.
Fields
- status: ExitStatus
- stdout: string
- stderr: string
Enum ProcessError
Structured process failures.
Variants
InvalidArguments(string)LaunchFailed(string)NotPipedThe stream was not
Stdio.Pipedor was already taken.System(i64)The operating system refused a wait or signal with this error code.
TimedOut(duration)Command.outputreached its configured runtime limit.OutputLimitExceeded(i64)Command.outputwould retain more than this many raw output bytes.
Struct Child
A running or finished child process.
Fields
- handle: ChildHandle
Inherent methods
impl Command
fn output(self, limits: CaptureLimits) -> CommandOutput fails ProcessError
Run without a shell and capture stdout and stderr within limits.
Captures a snapshot without changing this command's configuration.
Stdout and stderr are piped regardless of their command settings. Stdin
may be inherited or null; Piped is refused because this operation does
not expose a writer. Use start for interactive input.
A nonzero exit is ordinary CommandOutput.status data. Exceeding either
limit returns a structured error without partial output, after killing
and reaping a child that is still running. Cancellation does the same.
The byte budget bounds retained raw output. Operating-system pipes,
backend read buffers, the current chunk, allocation capacity and UTF-8
conversion have separate memory costs.
fn output_with_options(self, limits: CaptureLimits, options: SpawnOptions) -> CommandOutput fails ProcessError
Capture output with a per-child environment and working directory.
Limits, stdio, cancellation and cleanup follow output.
impl Child
fn id(self) -> i64
The child's operating-system process ID.
fn stdin(self) -> Result<stream.Sink<bytes>, ProcessError>
Take the write end of the child's stdin pipe. Finishing the sink closes the pipe, so the child reads end of input.
fn stdout(self) -> Result<stream.Stream<bytes>, ProcessError>
Take the read end of the child's stdout pipe.
fn stderr(self) -> Result<stream.Stream<bytes>, ProcessError>
Take the read end of the child's stderr pipe.
fn wait(self) -> ExitStatus fails ProcessError
Wait for the child to exit and reap it. The task suspends and holds
no thread; a wait cancelled by scope within releases its watch and
leaves the child running and unreaped.
fn try_wait(self) -> Result<Option<ExitStatus>, ProcessError>
Reap the child if it has exited, without waiting.
fn terminate(self) -> Result<(), ProcessError>
Ask the child to stop: SIGTERM on Unix. Windows has no request to
stop, so this terminates the child like kill. A reaped child is not
signalled.
fn kill(self) -> Result<(), ProcessError>
Stop the child at once: SIGKILL on Unix, TerminateProcess on
Windows. A reaped child is not signalled.
fn close(consume self)
Release the child at scope exit, killing and reaping it first if it is still running.