Bash.CommandPort (Bash v0.6.0)

Copy Markdown View Source

Single interface for all user-facing OS process execution.

Provides two layers of API:

High-level API

execute/3 runs a command to completion, streaming output to a sink:

CommandPort.execute("cat", ["bigfile.txt"], sink: sink)

Low-level Process API

For callers that manage process lifecycles directly (JobProcess, Coproc):

{:ok, proc} = CommandPort.start_link(["cat"], opts)
CommandPort.write(proc, "data")
CommandPort.close_stdin(proc)
{:ok, data} = CommandPort.read(proc)
{:ok, 0} = CommandPort.await_exit(proc, 5000)

Streaming API

For pipeline streaming:

stream = CommandPort.stream(["sort"], input: upstream)

Internal plumbing (signal delivery, hostname lookup, named pipe creation) is exempt and continues to use System.cmd directly.

graph TD
  AST[AST.Command] --> CP[CommandPort]
  JP[JobProcess] --> CP
  CO[Coproc] --> CP
  PL[Pipeline] --> CP
  CM[Command builtin] --> CP
  CP --> EX[ExCmd / System.cmd]

Summary

Functions

Waits for the process to exit within the given timeout.

Closes the process stdin.

Closes the process stdout.

Returns the OS PID of the process.

Reads a chunk from the process stdout. Returns {:ok, data}, :eof, or {:error, reason}.

Creates an OS process stream via ExCmd.stream/2.

Executes a command via System.cmd/3.

Writes data to the process stdin.

Functions

await_exit(process, timeout)

@spec await_exit(pid(), non_neg_integer() | :infinity) ::
  {:ok, non_neg_integer()} | {:error, term()}

Waits for the process to exit within the given timeout.

close_stdin(process)

@spec close_stdin(pid()) :: :ok

Closes the process stdin.

close_stdout(process)

@spec close_stdout(pid()) :: :ok

Closes the process stdout.

os_pid(process)

@spec os_pid(pid()) :: {:ok, non_neg_integer()} | non_neg_integer()

Returns the OS PID of the process.

read(process)

@spec read(pid()) :: {:ok, binary()} | :eof | {:error, term()}

Reads a chunk from the process stdout. Returns {:ok, data}, :eof, or {:error, reason}.

start_link(cmd_parts, opts)

@spec start_link(
  [String.t()],
  keyword()
) :: {:ok, pid()} | {:error, term()}

Starts an OS process via ExCmd.Process.start_link/2.

stream(cmd_parts, opts)

@spec stream(
  [String.t()],
  keyword()
) :: Enumerable.t()

Creates an OS process stream via ExCmd.stream/2.

system_cmd(path, args, opts)

@spec system_cmd(String.t(), [String.t()], keyword()) ::
  {String.t(), non_neg_integer()}

Executes a command via System.cmd/3.

write(process, data)

@spec write(pid(), binary()) :: :ok | {:error, term()}

Writes data to the process stdin.