Cmd

exec! : Str, List Str => Result {} [ ExecFailed { command : Str, exit_code : I32 }, FailedToGetExitCode { command : Str, err : IOErr } ]

Simplest way to execute a command while inheriting stdin, stdout and stderr from parent. If you want to capture the output, use exec_output! instead.

# Call echo to print "hello world"
Cmd.exec!("echo", ["hello world"])?

exec_cmd! : Cmd => Result {} [ ExecCmdFailed { command : Str, exit_code : I32 }, FailedToGetExitCode { command : Str, err : IOErr } ]

Execute a Cmd while inheriting stdin, stdout and stderr from parent. You should prefer using exec! instead, only use this if you want to use env, envs or clear_envs. If you want to capture the output, use exec_output! instead.

# Execute `cargo build` with env var.
Cmd.new("cargo")
|> Cmd.arg("build")
|> Cmd.env("RUST_BACKTRACE", "1")
|> Cmd.exec_cmd!()?

exec_output! : Cmd => Result { stdout_utf8 : Str, stderr_utf8_lossy : Str } [ StdoutContainsInvalidUtf8 { cmd_str : Str, err : [ BadUtf8 { index : U64, problem : Str.Utf8Problem } ] }, NonZeroExitCode { command : Str, exit_code : I32, stdout_utf8_lossy : Str, stderr_utf8_lossy : Str }, FailedToGetExitCode { command : Str, err : IOErr } ]

Execute command and capture stdout and stderr.

Stdin is not inherited from the parent and any attempt by the child process to read from the stdin stream will result in the stream immediately closing.

Use exec_output_bytes! instead if you want to capture the output in the original form as bytes. exec_output_bytes! may also be used for maximum performance, because you may be able to avoid unnecessary UTF-8 conversions.

cmd_output =
    Cmd.new("echo")
    |> Cmd.args(["Hi"])
    |> Cmd.exec_output!()?

Stdout.line!("Echo output: ${cmd_output.stdout_utf8}")?

exec_output_bytes! : Cmd => Result { stderr_bytes : List U8, stdout_bytes : List U8 } [ FailedToGetExitCodeB InternalIOErr.IOErr, NonZeroExitCodeB { exit_code : I32, stderr_bytes : List U8, stdout_bytes : List U8 } ]

Execute command and capture stdout and stderr in the original form as bytes.

Stdin is not inherited from the parent and any attempt by the child process to read from the stdin stream will result in the stream immediately closing.

Use exec_output! instead if you want to get the output as UTF-8 strings.

cmd_output_bytes =
    Cmd.new("echo")
    |> Cmd.args(["Hi"])
    |> Cmd.exec_output_bytes!()?

Stdout.line!("${Inspect.to_str(cmd_output_bytes)}")? # {stderr_bytes: [], stdout_bytes: [72, 105, 10]}

exec_exit_code! : Cmd => Result I32 [ FailedToGetExitCode { command : Str, err : IOErr } ]

Execute command and inherit stdin, stdout and stderr from parent. Returns the exit code.

You should prefer using exec! or exec_cmd! instead, only use this if you want to take a specific action based on a specific non-zero exit code. For example, roc check returns exit code 1 if there are errors, and exit code 2 if there are only warnings. So, you could use exec_exit_code! to ignore warnings on roc check.

exit_code =
       Cmd.new("cat")
       |> Cmd.args(["non_existent.txt"])
       |> Cmd.exec_exit_code!()?

Stdout.line!("${Num.to_str(exit_code)}")? # "1"

Cmd

Represents a command to be executed in a child process.

env : Cmd, Str, Str -> Cmd

Add a single environment variable to the command.

# Run "env" and add the environment variable "FOO" with value "BAR"
Cmd.new("env")
|> Cmd.env("FOO", "BAR")

envs : Cmd, List ( Str, Str ) -> Cmd

Add multiple environment variables to the command.

# Run "env" and add the variables "FOO" and "BAZ"
Cmd.new("env")
|> Cmd.envs([("FOO", "BAR"), ("BAZ", "DUCK")])

clear_envs : Cmd -> Cmd

Clear all environment variables, and prevent inheriting from parent, only the environment variables provided by env or envs are available to the child.

# Represents "env" with only "FOO" environment variable set
Cmd.new("env")
|> Cmd.clear_envs
|> Cmd.env("FOO", "BAR")

new : Str -> Cmd

Create a new command to execute the given program in a child process.

arg : Cmd, Str -> Cmd

Add a single argument to the command. ❗ Shell features like variable subsitition (e.g. $FOO), glob patterns (e.g. *.txt), ... are not available.

# Represent the command "ls -l"
Cmd.new("ls")
|> Cmd.arg("-l")

args : Cmd, List Str -> Cmd

Add multiple arguments to the command. ❗ Shell features like variable subsitition (e.g. $FOO), glob patterns (e.g. *.txt), ... are not available.

# Represent the command "ls -l -a"
Cmd.new("ls")
|> Cmd.args(["-l", "-a"])