Skip to main content

std.os

Process-level helpers that live directly on std (not under a submodule) — system, exit, cwd, chdir, and pid. Call them with dot, like any module function. There is no std.os object — the std.os title is just this page's name (call std.system(...), not std.os.system(...)). See Overview.

Reference

std.system(command) // run a shell command -> {output, status}
std.exit([code]) // terminate the process
std.cwd() // current working directory (string)
std.chdir(path) // change cwd (returns nil)
std.pid() // current process ID (long)

std.system — run a command and capture its stdout

std.system(command) runs the command through the shell and returns an object with two fields:

  • output — a string of everything the command wrote to stdout.
  • status — the process exit code (0 on success, non-zero on failure like 1 or 127).
var r = std.system("whoami")
print(r.status) // 0 (success)
print(r.output) // cory (what the command printed)

var date = std.system("date +%Y-%m-%d")
print("today is", date.output) // today is 2026-08-31

// capture multi-line output as a single string (with embedded newlines)
var ls = std.system("ls /tmp")
print(ls.output) // one file path per line

Captured output typically ends with a trailing newline, so when you embed it in another string you usually want to trim it:

var who = std.system("whoami").output
var name = std.string.trim(who) // drop the trailing newline
print("hello, " + name + "!")

Branch on the exit code:

var check = std.system("test -f /etc/hostname")
if (check.status == 0) {
print("file exists")
} else {
print("file missing")
}

print(std.system("exit 3").status) // 3 — the command's own exit code

:::note stdout only std.system captures stdout; any stderr the command writes goes straight to the script's stderr and is not included in output. Redirect inside the command if you need it, e.g. std.system("cmd 2>&1"). :::

std.cwd and std.chdir — the working directory

std.cwd() returns the current directory as a string; std.chdir(path) changes it (returning nil). They work together:

print(std.cwd()) // e.g. /home/user/projects
std.chdir("/tmp")
print(std.cwd()) // /tmp — the process cwd has changed
std.chdir("..") // relative paths work too

This matters because file operations and relative paths resolve against the process working directory.

std.cwd vs std.path.cwd

CallWhere it livesWhat it does
std.cwd()std.os (this page)Returns process CWD as a string
std.path.cwd()std.pathSame value, but alongside join/resolve/exists

Prefer std.cwd() for quick checks; use std.path.cwd() when you are already working with std.path helpers. std.chdir(path) is the only way to change the directory (both reflect the same process state).

See also std.path (std.path.cwd) and std.file.

std.pid — the process id

std.pid() returns the current process ID as a long (unique only among currently-running processes):

print(std.pid()) // e.g. 95516

var tag = "proc-" + std.pid()
std.file.write("/tmp/" + tag + ".lock", "owned by " + std.pid())
print("announcing:", tag)

Run the same script twice and each writes its own file:

instance pid = 99716 my lock file: /tmp/proc-99716.lock
instance pid = 99735 my lock file: /tmp/proc-99735.lock

The pid is useful for prefixed log lines and for pid-named lock files.

See also

  • std.file — file I/O relative to cwd
  • std.pathjoin/resolve with cwd
  • std.env — environment that system inherits