Skip to content

Process Supervision

Chloë Strainge edited this page Oct 14, 2026 · 1 revision

Supervised processes and terminals

Ordinary command syntax is convenient for interactive work. run_process provides structured control when a script must set a deadline, environment, working directory, or stream files.

let $result = run_process ["/usr/bin/printf", "%s", "inspection"] [
    "stdout_file": "inspection.txt", "timeout_ms": 1000]
let $text: String
"inspection.txt" -> $text
echo $result["exit_code"] $result["timed_out"] $text
0 false inspection

The command is an array of arguments; it is not a shell command string. Options include cwd, env, stdin_file, stdout_file, stderr_file, and timeout_ms. Omitting env inherits exported variables. Supplying an env map replaces the entire child environment; [:] clears it. Stream file paths are resolved relative to the calling shell, independently of the child's cwd. The runner does not invoke a second shell for parsing.

The result hash separates exit_code, signal, timed_out, and launch error. A deadline supervises the process group, terminates/escalates when needed, and reaps the child. Inspect these fields rather than assuming every failure is a nonzero normal exit.

let $result = run_process ["/usr/bin/printenv", "SHELLY_WIKI_ONLY"] [
    "env": ["SHELLY_WIKI_ONLY": "limited"], "timeout_ms": 1000]
echo $result["exit_code"]
limited
0

Interactive child processes

open_terminal arguments options creates a child and returns a shared Terminal. Its options are cwd, env, rows, and columns; default dimensions are 40 by 140. terminal_write handle text sends input. terminal_read handle timeout_ms returns a hash with text, eof, timed_out, and process-result fields. A read timeout leaves the child running and does not imply EOF. Reads can return partial text; split UTF-8 sequences are retained until complete.

terminal_close handle stops and reaps the child group and returns its status. Closing again returns the same status; reading or writing after close is an error. Dropping the last handle also cleans up. Writes have a bounded deadline.

The native Terminal API owns a child pseudoterminal. It can send text and keys, read output with a deadline, select its initial dimensions, and close the child lifetime. This is how Shelly's own tests exercise a real REPL without using another shell as a wrapper.

A pseudoterminal and redirected process files serve different purposes: programs may change buffering, colors, and behavior when attached to a terminal. Use ordinary commands unless a script actually needs supervision or terminal driving.


Related: Commands · Errors and cleanup · Line editing

Clone this wiki locally