Run shell commands inside a running sandbox.
Unlike the rest of E2bEx, this talks directly to the sandbox's envd daemon
(not api.e2b.app) over the Connect protocol. v1 supports blocking execution:
the command runs to completion and the result is returned.
{:ok, result} = E2bEx.Commands.run(client, sandbox, "echo hello")
result.stdout # => "hello\n"
result.exit_code # => 0Output can be streamed as it arrives by passing :on_stdout / :on_stderr
callbacks; the fully accumulated result is still returned:
{:ok, _result} =
E2bEx.Commands.run(client, sandbox, "make",
on_stdout: &IO.write/1,
on_stderr: &IO.write/1)A command that runs returns {:ok, %E2bEx.CommandResult{}} regardless of its
exit code; {:error, %E2bEx.Error{}} is reserved for transport, connection, or
protocol failures.
Background execution
Use start/4 to run a command in the background; output arrives as messages and
E2bEx.CommandHandle.wait/1 returns the result:
{:ok, h} = E2bEx.Commands.start(client, sandbox, "sleep 1; echo done")
receive do
{ref, {:stdout, data}} when ref == h.ref -> IO.write(data)
end
{:ok, result} = E2bEx.CommandHandle.wait(h)Control a running command with E2bEx.CommandHandle.kill/1, send_stdin/2,
close_stdin/1, disconnect/1, or the by-pid kill/4, send_stdin/5,
close_stdin/4, list/2, and connect/4.
Summary
Functions
Close a process's stdin (EOF) by pid.
Reconnect to a running command by pid and return a CommandHandle that streams
its output (/process.Process/Connect). Options: :subscriber, :timeout_ms,
:domain, :port, :base_url.
Kill a process by pid (SIGKILL). {:ok, false} if it was already gone.
List running commands/PTYs in sandbox (/process.Process/List).
Run command in sandbox and wait for it to finish.
Send data to a process's stdin by pid (requires the process was started with stdin: true).
Start command in sandbox in the background and return a CommandHandle.
Functions
@spec close_stdin(E2bEx.Client.t(), E2bEx.Sandbox.t(), non_neg_integer(), keyword()) :: :ok | {:error, E2bEx.Error.t()}
Close a process's stdin (EOF) by pid.
@spec connect(E2bEx.Client.t(), E2bEx.Sandbox.t(), non_neg_integer(), keyword()) :: {:ok, E2bEx.CommandHandle.t()} | {:error, E2bEx.Error.t()}
Reconnect to a running command by pid and return a CommandHandle that streams
its output (/process.Process/Connect). Options: :subscriber, :timeout_ms,
:domain, :port, :base_url.
@spec kill(E2bEx.Client.t(), E2bEx.Sandbox.t(), non_neg_integer(), keyword()) :: {:ok, boolean()} | {:error, E2bEx.Error.t()}
Kill a process by pid (SIGKILL). {:ok, false} if it was already gone.
@spec list(E2bEx.Client.t(), E2bEx.Sandbox.t(), keyword()) :: {:ok, [E2bEx.ProcessInfo.t()]} | {:error, E2bEx.Error.t()}
List running commands/PTYs in sandbox (/process.Process/List).
@spec run(E2bEx.Client.t(), E2bEx.Sandbox.t(), String.t(), keyword()) :: {:ok, E2bEx.CommandResult.t()} | {:error, E2bEx.Error.t()}
Run command in sandbox and wait for it to finish.
sandbox is an %E2bEx.Sandbox{} and must carry a :sandbox_id and an
:envd_access_token. Use a sandbox from E2bEx.Sandboxes.create/2,
connect/3, or get/2 — these return the access token. A sandbox from
list/2 does not carry the token (the API omits it from listed
sandboxes), so envd will reject the request with 401; call connect/3 or
get/2 on its sandbox_id first. client supplies shared Req config via
its :req_options.
Options
:on_stdout—(String.t() -> any())invoked with each stdout chunk as it arrives.:on_stderr—(String.t() -> any())invoked with each stderr chunk as it arrives.:cwd— working directory.:envs— environment variables (%{String.t() => String.t()}).:user— Linux user to run as (adds anAuthorization: Basicheader).:timeout_ms— total command timeout; default60000,0disables. (defaults are defined inE2bEx.Envd.Rpc):domain— override the sandbox domain.:port— envd port; default49983.:base_url— override the full envd base URL (advanced; self-hosted/testing).
Callbacks run synchronously in arrival order from the calling process; a callback that raises propagates to the caller.
@spec send_stdin( E2bEx.Client.t(), E2bEx.Sandbox.t(), non_neg_integer(), binary(), keyword() ) :: :ok | {:error, E2bEx.Error.t()}
Send data to a process's stdin by pid (requires the process was started with stdin: true).
@spec start(E2bEx.Client.t(), E2bEx.Sandbox.t(), String.t(), keyword()) :: {:ok, E2bEx.CommandHandle.t()} | {:error, E2bEx.Error.t()}
Start command in sandbox in the background and return a CommandHandle.
Output is streamed to the subscriber (opts[:subscriber], default the calling
process) as {handle.ref, {:stdout|:stderr, binary}} messages, ending with a
terminal {handle.ref, {:exit, %E2bEx.CommandResult{}}} (any exit code) or
{handle.ref, {:error, %E2bEx.Error{}}}. Use the message stream or
E2bEx.CommandHandle.wait/1.
Options
:subscriber— pid to receive output messages (default the caller).:stdin— open stdin sosend_stdin/2works (defaultfalse).:cwd,:envs,:user,:timeout_ms,:domain,:port,:base_url— as forrun/4.