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 (0on success, non-zero on failure like1or127).
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
| Call | Where it lives | What it does |
|---|---|---|
std.cwd() | std.os (this page) | Returns process CWD as a string |
std.path.cwd() | std.path | Same 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.