child_process
Types
A builder for configuring and spawning child processes.
Use from_file() or from_name() to create a builder, then chain
configuration methods like arg(), env(), and cwd() before
calling run() or spawn().
Example
child_process.from_name("node")
|> child_process.arg("server.js")
|> child_process.env("PORT", "3000")
|> child_process.cwd("/app")
|> child_process.run(stdio.capture(True))
pub type Builder =
@internal Builder
The result of running a process to completion. Contains the exit status code and captured output.
pub type Output {
Output(status_code: Int, output: String)
}
Constructors
-
Output(status_code: Int, output: String)The status code and captured output from the process.
Exit codes:
0typically indicates success-1indicates the process was killed (viakill())-2indicates the process failed to start (only on JavaScript target)- Other non-zero values are process-specific error codes
When no output was configured to be captured,
outputwill be empty.
A handle to a running child process.
Use the process control functions like write(), stop(), and kill()
to interact with the process.
pub type Process =
@internal Process
An error that occurred when trying to start a process.
pub type StartError {
OutOfMemory
OsProcessLimitReached
OsFileLimitReached
CommandTooLong
NotEnoughFileDescriptors
FileNotFound(String)
FileNotExecutable(String)
RuntimeLimitReached
}
Constructors
-
OutOfMemoryThe operating system does not have enough memory to spawn this process.
-
OsProcessLimitReachedThe operating system process table is full.
-
OsFileLimitReachedThe operating system file descriptor table is full.
-
CommandTooLongThe command is too long.
-
NotEnoughFileDescriptorsThe runtime process has too many open file descriptors.
-
FileNotFound(String)The executable file was not found at the specified path.
-
FileNotExecutable(String)The file exists but is not executable.
-
RuntimeLimitReachedA runtime resource limit prevented the process from starting.
An error that occurred while sending data to the process.
pub type WriteError {
WriteAborted
ProcessExited
}
Constructors
-
WriteAbortedThe process can’t be written to right now or writing was cancelled.
-
ProcessExitedThe process you tried to write to already exited.
Values
pub fn arg(builder: Builder, argument: String) -> Builder
Add a command-line argument to the process.
pub fn arg2(
builder: Builder,
argument: String,
value: String,
) -> Builder
Add 2 command-line arguments to the process. Useful when adding option/argument pairs!
pub fn args(builder: Builder, args: List(String)) -> Builder
Add multiple command-line arguments to the process.
pub fn cwd(builder: Builder, directory: String) -> Builder
Set the working directory for the process.
pub fn describe_start_error(error: StartError) -> String
Convert a StartError into a human-readable string.
pub fn describe_write_error(error: WriteError) -> String
Convert a WriteError into a human-readable string.
pub fn env(
builder: Builder,
key: String,
value: String,
) -> Builder
Set an environment variable for the process.
Environment variables set here are merged with the parent process’s environment, not replaced.
pub fn envs(
builder: Builder,
environment: List(#(String, String)),
) -> Builder
Set multiple environment variables for the process.
Environment variables set here are merged with the parent process’s environment, not replaced.
pub fn exec(
run command: String,
with arguments: List(String),
in directory: String,
) -> Result(Output, StartError)
Execute a command with arguments in a specific directory.
Example
exec(run: "git", with: ["status"], in: "/path/to/repo")
pub fn factory(
stdio stdio: stdio.Stdio,
) -> factory_supervisor.Builder(Builder, Process)
Create a factory supervisor builder for dynamically spawning supervised processes.
The stdio configuration determines how each child’s I/O is handled.
Example
import gleam/otp/factory_supervisor
let assert Ok(factory) =
child_process.factory(stdio: stdio.ignore())
|> factory_supervisor.start()
let worker_config =
child_process.new("node")
|> child_process.arg("worker.js")
factory_supervisor.start_child(factory, worker_config)
pub fn find_executable(name: String) -> Result(String, Nil)
Find an executable by name in the system PATH. Returns the absolute path to the executable if found.
Example
find_executable("git")
// -> Ok("/usr/bin/git")
pub fn from_file(executable_path: String) -> Builder
Create a new process builder with the given executable path.
Example
from_file("/usr/bin/git")
|> arg("status")
|> run(stdio.capture(True))
pub fn from_name(executable_name: String) -> Builder
Create a new process builder, searching for the executable in PATH.
Example
from_name("git")
|> arg("status")
|> run(stdio.capture(True))
pub fn is_running(process: Process) -> Bool
Returns True if the process is still running.
pub fn kill(process: Process) -> Nil
Forcefully kill the process (SIGKILL on Unix, taskkill /F on Windows).
The process is terminated immediately without cleanup. Use stop() first
to give the process a chance to exit gracefully.
pub fn open(target: String) -> Result(Nil, StartError)
Open a URL or file with the system’s default application.
Returns immediately on all platforms. The opened application runs fully detached from the Erlang VM.
Example
child_process.open("https://gleam.run")
// -> Ok(Nil)
child_process.open("/path/to/document.pdf")
// -> Ok(Nil)
pub fn os_process_id(process: Process) -> Result(Int, Nil)
Get the operating system process ID.
pub fn reveal(path: String) -> Result(Nil, StartError)
Reveal a file in the system’s file manager (Finder, Explorer, etc).
Example
child_process.reveal("/path/to/file.txt")
// -> Ok(Nil)
pub fn run(
builder: Builder,
mode mode: stdio.Mode,
) -> Result(Output, StartError)
Run the process synchronously and wait for it to complete.
When mode is capture(_), output is captured and returned in Output.output.
When mode is null() or inherit(), output is empty.
Example
child_process.from_file("/bin/echo")
|> child_process.arg("hello")
|> child_process.run(stdio.capture(True))
pub fn shell(cmd: String) -> Result(String, StartError)
Execute a shell command string using the system shell.
On Windows, uses cmd.exe. On Unix-like systems, uses /bin/sh.
Example
shell("echo Hello, World!")
pub fn spawn(
builder: Builder,
stdio stdio: stdio.Stdio,
) -> Result(Process, StartError)
Spawn the process asynchronously with a stdio handler.
The stdio configuration determines both the I/O mode (how the port is configured) and the callbacks (how data is consumed). The handler is applied immediately after spawning.
On Erlang, this spawns an extra process that manages the port.
Example
let assert Ok(proc) =
child_process.from_name("node")
|> child_process.arg("server.js")
|> child_process.spawn(stdio.lines(fn(line) { io.println(line) }))
Note: On JavaScript, Node delivers errors asynchronously, so this implementation makes various checks beforehand to be reasonably sure that the call will succeed.
pub fn spawn_raw(
builder: Builder,
mode mode: stdio.Mode,
) -> Result(Process, StartError)
Spawn the process asynchronously without attaching an extra process or event listeners.
On Erlang, the port is opened in the calling process. Port messages
arrive in the caller’s mailbox and can be received via stdio.select().
Example
let assert Ok(proc) =
child_process.from_file("my_program")
|> child_process.spawn_raw(stdio.capture(True))
let selector =
process.new_selector()
|> stdio.select(proc, HandleData, HandleExit)
Note: On JavaScript, Node delivers errors asynchronously, so this implementation makes various checks beforehand to be reasonably sure that the call will succeed.
pub fn stop(process: Process) -> Nil
Stop the process gracefully (SIGTERM on Unix, taskkill on Windows).
The process has the opportunity to perform cleanup before exiting.
If the process doesn’t exit on its own, you may need to call kill()
to forcefully terminate it.
pub fn supervised(
builder: Builder,
stdio stdio: stdio.Stdio,
) -> supervision.ChildSpecification(Process)
Create a child specification for use with OTP supervisors.
The stdio configuration determines both how I/O is handled and how data is consumed. The intermediate process created by the handler is what the supervisor monitors.
When the supervisor shuts down, the intermediate process receives a shutdown signal and sends SIGTERM to the OS process.
Example
import gleam/otp/static_supervisor as supervisor
supervisor.new(supervisor.OneForOne)
|> supervisor.add(
child_process.new("node")
|> child_process.arg("server.js")
|> child_process.supervised(stdio.lines(fn(line) {
io.println(line)
}))
)
pub fn write(
process: Process,
text: String,
) -> Result(Nil, WriteError)
Write text to the process’s stdin, without appending a newline character.
Note: Writing to stdin is not supported when using stdio.inherit(),
as the stdin stream is connected directly to the parent’s terminal.
pub fn writeln(
process: Process,
text: String,
) -> Result(Nil, WriteError)
Write a line of text to the process’s stdin.