Skip to content

proc.run

The proc.run module provides access to external programs.

Accessing Programs

Use proc.run as a namespace to access programs by name:

run.ls -la
run.git status
run["/bin/echo"] hello world
run[Path "tools/build.sh"] --help

Or import specific programs:

import proc.run:
  - ls
  - git
  - curl

ls -la
git status

Or call it with the program as a first argument:

run cat Cargo.toml

Program Execution

When a program object is called, it spawns the external program with the given arguments. Arguments are converted to strings using std.arg.

run.echo hello world
# Runs: /usr/bin/echo hello world

Key Arguments

Name Type Description
stdin? iterable|path|handle Source for the program's standard input
stdout? sink|path|handle Target for the program's standard output
stderr? sink|path|handle|sym Target for the program's standard error
policy? dict Termination policy overrides

I/O Redirection

Omitted, programs participate in Do's I/O system:

  • Program stdin is connected to the current input
  • Program stdout is connected to the current output
  • Program stderr goes to the console

This means programs work naturally in pipelines:

import strand

let result = strand.pipeline
  do run.cat /etc/passwd
  do run.grep nologin
  do strand.each do |line| [...line.split ":"]
  do strand.collect()

Given explicitly, each accepts:

  • A str or fs.Path, which is opened as a file for the appropriate direction.
  • Any iterable (stdin:) or sink (stdout:/stderr:), including arrays, pipeline ends, and fs.File handles. Values crossing this boundary are framed per the ambient I/O mode.
  • One of the shell.stdin, shell.stdout, or shell.stderr handles, which hands the program the corresponding stream directly.
  • nil or NULLITER, discarding the stream.

stderr: :stdout: merges the program's standard error into whatever its standard output is connected to.

run.tar czf archive.tar.gz src stderr: :stdout:
run.make -j8 stdout: build.log stderr: build.log
run.sort stdin: ["c", "a", "b"] stdout: $sorted

An omitted stderr: defaults to term.default, which follows console/terminal interception such as progress module indicators or term.capture. Naming shell.stdout/shell.stderr explicitly opts out of that entirely.

See Terminal output for the full model.

Termination Policy

Use the policy: dictionary to override termination behavior for one launch. Unspecified fields inherit the current proc.with_policy settings.

Key Type Description
signal sym|int Unix signal name or target-native number
grace Duration|float Time to wait for process to exit after termination signal
force bool Force termination after the grace period
run worker policy: {signal: :INT:, grace: 10.0, force: true}

Foreground Unix processes are terminated directly. Processes launched under strand.spawn or strand.stream are placed in a separate process group and terminated as a group. Windows uses CTRL_BREAK_EVENT; background launches are force-terminated through a Job Object. A signal override is invalid for a Windows target.

Capturing Output

Use sub to capture a program's standard output as a string:

let kernel = sub do run.uname -r
echo "Kernel: $kernel"

To capture all console-bound output, use term.sub; this picks up unredirected undirected stderr.

let complaints = term.sub do run.mytool

Environment

Programs inherit the current environment from shell.env. Use the shell.env function to set variables for a specific invocation:

env LANG: C do
  run.sort input.txt

Program Methods

which()

Returns the resolved path to the program executable, if found.

echo $run.ls.which()
# Prints: /usr/bin/ls

echo $run.nonexistent.which()
# Prints: nil