Mojo os and sys Modules
The os and sys modules give your program access to the operating system and runtime environment. You use them to read environment variables, work with file paths, list directory contents, check system information, and control program exit behavior. Mojo provides a native sys module and accesses Python's full os and sys through interop.
Mojo's Native sys Module
from sys import argv, exit, stdin, stdout, stderr
fn main():
# argv() already covered in Command Line Args topic
var args = argv()
print("Program:", args[0])
# Exit with a status code
# 0 = success, non-zero = error (Unix convention)
if len(args) < 2:
print("Missing argument")
exit(1) # exit immediately with error code
print("Argument received:", args[1])
exit(0) # explicit success exit
System Information with sys.info
from sys.info import (
os_is_linux, os_is_macos, os_is_windows,
is_x86, is_apple_m1,
simdwidthof, simdbytewidth,
num_physical_cores, num_logical_cores,
)
fn main():
print("Linux:", os_is_linux())
print("macOS:", os_is_macos())
print("x86:", is_x86())
# SIMD width for float32 on this CPU
alias float32_simd_width = simdwidthof[DType.float32]()
print("Float32 SIMD width:", float32_simd_width) # 8 on AVX2
print("Physical cores:", num_physical_cores())
print("Logical cores:", num_logical_cores())
Typical output on an AVX2 laptop: Linux: True macOS: False x86: True Float32 SIMD width: 8 Physical cores: 8 Logical cores: 16
Environment Variables
from python import Python
fn get_env(key: String, default: String = "") raises -> String:
var os = Python.import_module("os")
var val = os.environ.get(key, default)
return str(val)
fn main() raises:
var home = get_env("HOME", "/tmp")
var path = get_env("PATH", "")
var user = get_env("USER", "unknown")
print("Home:", home)
print("User:", user)
print("PATH has entries:", len(path.split(":")))
Environment variables are key=value pairs the OS provides: HOME=/home/alice → user's home directory PATH=/usr/bin:... → where the shell looks for commands USER=alice → current username TERM=xterm-256color → terminal type LANG=en_US.UTF-8 → language/locale setting
Setting Environment Variables
from python import Python
fn main() raises:
var os = Python.import_module("os")
# Set a variable for this process and its children
os.environ["MY_APP_MODE"] = "production"
os.environ["MY_APP_PORT"] = "8080"
# Read it back
print(str(os.environ.get("MY_APP_MODE", ""))) # production
print(str(os.environ.get("MY_APP_PORT", ""))) # 8080
File Path Operations
from python import Python
fn main() raises:
var os = Python.import_module("os")
var path = os.path
# Current working directory
var cwd = str(os.getcwd())
print("CWD:", cwd)
# Join paths safely (handles / correctly on all OSes)
var full_path = str(path.join(cwd, "data", "results.csv"))
print("Full path:", full_path)
# Check existence
print("Exists:", bool(path.exists(full_path)))
print("Is file:", bool(path.isfile(full_path)))
print("Is dir:", bool(path.isdir(cwd)))
# Split a path into directory and filename
var parts = path.split("/home/alice/project/data.csv")
print("Dir: ", str(parts[0])) # /home/alice/project
print("File:", str(parts[1])) # data.csv
# Get file extension
var ext_parts = path.splitext("report.pdf")
print("Extension:", str(ext_parts[1])) # .pdf
path.join() diagram:
os.path.join("/home/alice", "data", "scores.csv")
↓
"/home/alice/data/scores.csv"
Works on Linux/macOS (/) and Windows (\) automatically.
Never manually concatenate paths with string + "/" + string.
Listing Directory Contents
from python import Python
fn main() raises:
var os = Python.import_module("os")
# List all entries in current directory
var entries = os.listdir(".")
for i in range(int(len(entries))):
print(str(entries[i]))
# Walk a directory tree recursively
var walk = os.walk(".")
for item in walk:
var root = str(item[0]) # current directory
var files = item[2] # files in this directory
for j in range(int(len(files))):
print(root + "/" + str(files[j]))
Creating and Removing Directories
from python import Python
fn main() raises:
var os = Python.import_module("os")
# Create a directory (fails if exists)
try:
os.mkdir("output")
print("Directory created")
except:
print("Directory already exists")
# Create nested directories
os.makedirs("output/reports/2025", exist_ok=True)
print("Nested dirs created")
# Remove an empty directory
# os.rmdir("output/reports/2025")
# Remove directory tree (be careful!)
var shutil = Python.import_module("shutil")
# shutil.rmtree("output") # removes everything recursively
Checking CPU and Memory
from python import Python
fn main() raises:
var psutil = Python.import_module("psutil")
var cpu_count = int(psutil.cpu_count())
var mem = psutil.virtual_memory()
var mem_total = int(mem.total) // (1024 * 1024 * 1024)
var mem_used = int(mem.used) // (1024 * 1024 * 1024)
print("CPU cores:", cpu_count)
print("RAM total:", mem_total, "GB")
print("RAM used:", mem_used, "GB")
print("RAM percent:", float(mem.percent), "%")
Running Shell Commands
from python import Python
fn run_command(cmd: String) raises -> String:
var subprocess = Python.import_module("subprocess")
var result = subprocess.run(
cmd, shell=True, capture_output=True, text=True
)
return str(result.stdout)
fn main() raises:
var output = run_command("ls -la")
print(output)
var hostname = run_command("hostname").strip()
print("Running on:", hostname)
Key Takeaways
Mojo's native sys module provides argv(), exit(), and sys.info for CPU and OS detection at compile time. Use Python's os module through interop for environment variables, file path manipulation, directory listing, and process management. Always use os.path.join() to build file paths — never concatenate strings with slashes manually. os.makedirs(path, exist_ok=True) creates nested directories safely. Read environment variables with os.environ.get(key, default). Use subprocess.run() to execute shell commands and capture their output. Detect the current platform with os_is_linux(), os_is_macos(), and is_x86() from sys.info for platform-specific code paths.
