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.

Leave a Comment

Your email address will not be published. Required fields are marked *