ChildProcess unstable
Describes child processes before they are started.
A Command stores the executable, arguments, environment, standard streams,
working directory, and other process options. Commands can also be piped
together. A command is an Effect; running it asks the
ChildProcessSpawner service to start the process and returns a
ChildProcessHandle.
Combinators
Pipes the output of one command to the input of another.
Details
By default, pipes stdout from the source to stdin of the destination.
Use the options parameter to customize which streams are connected.
Signature
declare const pipeTo: { (that: Command, options?: PipeOptions): (self: Command) => PipedCommand; (self: Command, that: Command, options?: PipeOptions): PipedCommand;}Example Piping command output
import { ChildProcess } from "effect/process"
// Pipe stdout (default)const pipeline1 = ChildProcess.make`cat file.txt`.pipe( ChildProcess.pipeTo(ChildProcess.make`grep pattern`))
// Pipe stderr instead of stdoutconst pipeline2 = ChildProcess.make`my-program`.pipe( ChildProcess.pipeTo(ChildProcess.make`grep error`, { from: "stderr" }))
// Pipe combined stdout and stderrconst pipeline3 = ChildProcess.make`my-program`.pipe( ChildProcess.pipeTo(ChildProcess.make`tee output.log`, { from: "all" }))
const result = [pipeline1._tag, pipeline2.options.from, pipeline3.options.from]result // => ["PipedCommand", "stderr", "all"]Prepends another command to a command.
Details
For pipelines, only the leftmost command is prefixed.
Signature
declare const prefix: { (command: string, args?: readonly Array<Word>): (self: Command) => Command; (templates: TemplateStringsArray, ...expressions: readonly Array<TemplateExpression>): (self: Command) => Command; (self: Command, command: string, args?: readonly Array<Word>): Command;}Example Prefixing commands
import { ChildProcess } from "effect/process"
const command = ChildProcess.make`echo foo`
const prefixed = command.pipe( ChildProcess.prefix`time`)
// now prefixed will execute `time echo "foo"`const result = prefixed._tag === "StandardCommand" ? `${prefixed.command} ${prefixed.args[0]}` : prefixed._tagresult // => "time echo"Sets the current working directory for a command.
Details
For pipelines, applies to each command in the pipeline.
Signature
declare const setCwd: { (cwd: string): (self: Command) => Command; (self: Command, cwd: string): Command;}Example Setting command working directories
import { ChildProcess } from "effect/process"
const cmd = ChildProcess.make`ls -la`.pipe( ChildProcess.setCwd("/tmp"))const result = cmd._tag === "StandardCommand" && cmd.options.cwd // => "/tmp"Adds environment variables to a command, merging them with any existing command environment and overriding duplicate keys.
Details
For pipelines, applies to each command in the pipeline.
Signature
declare const setEnv: { (env: Record<string, string | Redacted.Redacted<string>>): (self: Command) => Command; (self: Command, env: Record<string, string | Redacted.Redacted<string>>): Command;}Example Setting command environment variables
import { ChildProcess } from "effect/process"
const cmd = ChildProcess.make`node script.js`.pipe( ChildProcess.setEnv({ NODE_ENV: "test" }))const result = cmd._tag === "StandardCommand" && cmd.options.env?.NODE_ENV // => "test"Constructors
Create a command from a template literal, options + template, or array form.
Details
This function supports three calling conventions:
- Template literal:
make\npm run build`` - Options + template literal:
make({ cwd: "/app" })\npm run build`` - Array form:
make("npm", ["run", "build"], options?)
Templates are split with CommandLine.template: quotes group words, each
${} value is one literal argument, and an argument that contains a
Redacted value stays Redacted. Arguments in the array form can be
Redacted too.
With the shell option, the template text is the shell script and is kept
as written.
Gotchas
- A template is parsed when
makeis called. Shell syntax such as|,$HOME,*or~throws aCommandLine.CommandLineError: quote it, or pass the value with${}. - A template with the
shelloption cannot contain${}values, because their quoting depends on the shell. Build the script withCommandLine.quoteand pass it as a string. - The program name, the first word, cannot be
Redacted. - A NUL character in the command, an argument or an
envvalue fails with aBadArgumenterror when the command is spawned.
Signature
declare const make: { (command: string, options?: CommandOptions): StandardCommand; (command: string, args: readonly Array<Word>, options?: CommandOptions): StandardCommand; (options: CommandOptions): (templates: TemplateStringsArray, ...expressions: readonly Array<TemplateExpression>) => StandardCommand; (templates: TemplateStringsArray, ...expressions: readonly Array<TemplateExpression>): StandardCommand;}Example Creating commands
import { ChildProcess } from "effect/process"
// Template literal form; quotes group wordsconst cmd1 = ChildProcess.make`echo "hello world"`
// With optionsconst cmd2 = ChildProcess.make({ cwd: "/tmp" })`ls -la`
// Array formconst cmd3 = ChildProcess.make("git", ["status"])
const result = [cmd1.args[0], cmd2.options.cwd, cmd3.args[0]] // => ["hello world", "/tmp", "status"]Converting
Create an fd name from its numeric index.
Signature
declare function fdName(fd: number): stringparseFdName
unstableParses an fd name like "fd3" to its numeric index. Returns undefined if the name is invalid.
Signature
declare function parseFdName(name: string): number | undefinedGuards
Checks whether a value is a Command.
Signature
declare function isCommand(u: unknown): u is CommandisPipedCommand
unstableChecks whether a command is a PipedCommand.
Signature
declare function isPipedCommand(command: Command): command is PipedCommandisStandardCommand
unstableChecks whether a command is a StandardCommand.
Signature
declare function isStandardCommand(command: Command): command is StandardCommandModels
Configuration for additional file descriptors to expose to the child process.
Signature
type AdditionalFdConfig = { readonly stream?: Stream.Stream<Uint8Array, PlatformError.PlatformError>; readonly type: "input";} | { readonly sink?: Sink.Sink<Uint8Array, Uint8Array, never, PlatformError.PlatformError>; readonly type: "output";} | { readonly sink?: Sink.Sink<Uint8Array, Uint8Array, never, PlatformError.PlatformError>; readonly stream?: Stream.Stream<Uint8Array, PlatformError.PlatformError>; readonly type: "duplex";}A command that can be built using make, combined using pipeTo, and executed using exec or spawn.
Signature
type Command = StandardCommand | PipedCommandInput type for child process stdin.
Signature
type CommandInput = "pipe" | "inherit" | "ignore" | "overlapped" | Stream.Stream<Uint8Array, PlatformError.PlatformError>Output type for child process stdout/stderr.
Signature
type CommandOutput = "pipe" | "inherit" | "ignore" | "overlapped" | Sink.Sink<Uint8Array, Uint8Array, never, PlatformError.PlatformError>The encoding format to use for binary data.
Signature
type Encoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "utf-16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex"A pipeline of commands where the output of one is piped to the input of the next.
Signature
interface PipedCommand extends Effect<ChildProcessHandle, PlatformError.PlatformError, ChildProcessSpawner | Scope.Scope> { readonly _tag: "PipedCommand"; readonly left: Command; readonly options: PipeOptions; readonly right: Command;}Specifies which stream to pipe from the source subprocess.
Details
"stdout": Pipe stdout from the source (default)"stderr": Pipe stderr from the source"all": Pipe both stdout and stderr interleaved`fd${number}`: Pipe from a custom file descriptor (e.g.,"fd3")
Signature
type PipeFromOption = "stdout" | "stderr" | "all" | `fd${number}`Specifies which input to pipe to on the destination subprocess.
Details
"stdin": Pipe to stdin of the destination (default)`fd${number}`: Pipe to a custom file descriptor (e.g.,"fd3")
Signature
type PipeToOption = "stdin" | `fd${number}`A signal that can be sent to a child process.
Signature
type Signal = "SIGABRT" | "SIGALRM" | "SIGBUS" | "SIGCHLD" | "SIGCONT" | "SIGFPE" | "SIGHUP" | "SIGILL" | "SIGINT" | "SIGIO" | "SIGIOT" | "SIGKILL" | "SIGPIPE" | "SIGPOLL" | "SIGPROF" | "SIGPWR" | "SIGQUIT" | "SIGSEGV" | "SIGSTKFLT" | "SIGSTOP" | "SIGSYS" | "SIGTERM" | "SIGTRAP" | "SIGTSTP" | "SIGTTIN" | "SIGTTOU" | "SIGUNUSED" | "SIGURG" | "SIGUSR1" | "SIGUSR2" | "SIGVTALRM" | "SIGWINCH" | "SIGXCPU" | "SIGXFSZ" | "SIGBREAK" | "SIGLOST" | "SIGINFO"A standard command with pre-parsed command and arguments.
Signature
interface StandardCommand extends Effect<ChildProcessHandle, PlatformError.PlatformError, ChildProcessSpawner | Scope.Scope> { readonly _tag: "StandardCommand"; readonly args: readonly Array<Word>; readonly command: string; readonly options: CommandOptions;}Configuration for the child process standard error stream.
Signature
interface StderrConfig { readonly stream?: CommandOutput;}Configuration for the child process standard input stream.
Signature
interface StdinConfig { readonly encoding?: Encoding; readonly endOnDone?: boolean; readonly stream: CommandInput;}Configuration for the child process standard output stream.
Signature
interface StdoutConfig { readonly stream?: CommandOutput;}Options
Options for command execution.
Signature
interface CommandOptions extends KillOptions { readonly additionalFds?: Record<`fd${number}`, AdditionalFdConfig>; readonly cwd?: string; readonly detached?: boolean; readonly env?: Record<string, string | Redacted<string> | undefined>; readonly extendEnv?: boolean; readonly shell?: string | boolean; readonly stderr?: CommandOutput | StderrConfig; readonly stdin?: StdinConfig | CommandInput; readonly stdout?: StdoutConfig | CommandOutput; readonly windowsHide?: boolean;}Options that can be used to control how a child process is terminated.
Signature
interface KillOptions { readonly forceKillAfter?: Input; readonly killSignal?: Signal;}Options for controlling how commands are piped together.
Signature
interface PipeOptions { readonly from?: PipeFromOption; readonly to?: PipeToOption;}Example Piping stderr between commands
import { ChildProcess } from "effect/process"
// Pipe stderr instead of stdoutconst pipeline = ChildProcess.make`my-program`.pipe( ChildProcess.pipeTo(ChildProcess.make`grep error`, { from: "stderr" }))const result = [pipeline._tag, pipeline.options.from] // => ["PipedCommand", "stderr"]