E2bEx.Commands (E2bEx v0.1.0)

Copy Markdown View Source

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 # => 0

Output 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

close_stdin(client, sandbox, pid, opts \\ [])

@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.

connect(client, sandbox, pid, opts \\ [])

@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.

kill(client, sandbox, pid, opts \\ [])

@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.

list(client, sandbox, opts \\ [])

@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).

run(client, sandbox, command, opts \\ [])

@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 an Authorization: Basic header).
  • :timeout_ms — total command timeout; default 60000, 0 disables. (defaults are defined in E2bEx.Envd.Rpc)
  • :domain — override the sandbox domain.
  • :port — envd port; default 49983.
  • :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.

send_stdin(client, sandbox, pid, data, opts \\ [])

@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).

start(client, sandbox, command, opts \\ [])

@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 so send_stdin/2 works (default false).
  • :cwd, :envs, :user, :timeout_ms, :domain, :port, :base_url — as for run/4.