Skip to content

capture

Eugene Lazutkin edited this page Jul 11, 2026 · 1 revision

capture runs a process and collects its outputs in memory — the one-call scripting and testing primitive (think shell backticks). It is a tag function that mirrors $ with the same options chaining, but resolves to the collected stdout/stderr strings along with the exit status.

Usage

import {capture} from 'dollar-shell';

const {code, stdout, stderr} = await capture`git rev-parse HEAD`;

Docs

The TypeScript declaration:

interface CaptureOptions extends SpawnOptions {
  input?: string;
}

interface CaptureResult extends DollarResult {
  stdout: string;
  stderr: string;
}

declare const capture: Dollar<Promise<CaptureResult>, CaptureOptions>;

SpawnOptions is defined in spawn(), DollarResult in $.

Differences from $:

  • stdout and stderr are forced to 'pipe' and collected as strings (UTF-8 decoded). The resolved object extends $'s result (code, signal, killed) with stdout and stderr.
  • input — an optional string written to the standard input of the process, which is then closed. When set, stdin is forced to 'pipe'.

Notes:

  • The env option is passed to spawn() unchanged — no merging with the parent environment. Spread it yourself to extend: env: {...process.env, FOO: '1'}.
  • Buffering is eager — the whole output is held in memory. For large outputs use the streaming tags ($.from, $.io).
  • Like every spawning function, capture honors the signal option (spawn()): on abort the process is killed and the result reports killed: true.

Examples

import {capture} from 'dollar-shell';

// collect stdout
const {stdout} = await capture`ls -l .`;

// string input to stdin
(await capture({input: 'some text'})`cat`).stdout === 'some text';

// exit status is reported, not thrown
const result = await capture`sh -c ${'exit 3'}`;
result.code === 3;

// abort kills the process
const controller = new AbortController();
const pending = capture({signal: controller.signal})`sleep 10`;
controller.abort();
(await pending).killed === true;

The same tag is available from dollar-shell/node — the result is identical (strings are stream-agnostic).

Clone this wiki locally