Skip to content
Plugins (183)

shell

stable

Execute shell commands, manage environment variables, and perform file system operations including path manipulation, directory traversal, and file I/O.

use plugin shell::{exec, exec_status, exec_lines, …}
46 functions Systems
Runs with the native Zolo host

Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.

/ filter jk navigate Esc clear
Functions (46)
  1. exec Run a shell command, return stdout/stderr/exit_code
  2. exec_status Run a command, return only the exit code
  3. exec_lines Run a command, return stdout as a table of lines
  4. exec_env Run a command with extra environment variables
  5. exec_in_dir Run a command in a specific working directory
  6. pipe Chain multiple commands with pipes
  7. which Find the path to a program on PATH
  8. env_get Read an environment variable
  9. env_set Set an environment variable
  10. env_remove Remove an environment variable
  11. env_list List all environment variables
  12. cwd Get the current working directory
  13. chdir Change the current working directory
  14. home_dir Get the user's home directory
  15. temp_dir Get the system temporary directory
  16. path_separator Get the OS path separator character
  17. os Get the operating system name
  18. arch Get the CPU architecture name
  19. is_windows Check if running on Windows
  20. is_linux Check if running on Linux
  21. is_macos Check if running on macOS
  22. glob Match file paths using a glob pattern
  23. exists Check if a path exists
  24. is_file Check if a path is a regular file
  25. is_dir Check if a path is a directory
  26. file_size Get a file's size in bytes
  27. read_file Read a file's content as a string
  28. write_file Write a string to a file
  29. append_file Append a string to a file
  30. mkdir Create a directory (and parents)
  31. rmdir Remove a directory recursively
  32. copy_file Copy a file to another path
  33. move_file Move or rename a file
  34. remove_file Delete a file
  35. list_dir List entries in a directory
  36. walk_dir Recursively list all files in a directory
  37. path_join Join path parts into a single path
  38. path_parent Get the parent directory of a path
  39. path_filename Get the filename component of a path
  40. path_extension Get the file extension of a path
  41. path_stem Get the filename without its extension
  42. absolute_path Resolve a path to its canonical absolute form
  43. shell_execute Open a file or URL with the OS shell verb
  44. resolve_shortcut Resolve a Windows .lnk shortcut file
  45. extract_icon Extract an icon from a file as PNG bytes
  46. read_directory_items List directory entries with metadata

From import to result

  1. 01Import only what you use
  2. 02Copy the smallest example
  3. 03Run it with the Zolo CLI

Overview

shell is the systems-programming bridge between a Zolo script and the host operating system. It groups three concerns under one plugin: running external commands (exec, pipe, exec_in_dir, …), reading and writing the environment (env_get, cwd, os, which, …), and manipulating the file system and paths (read_file, mkdir, glob, path_join, walk_dir, …). There is no handle or stateful object to manage — every function is a free call that acts directly on the live process, so changes such as chdir or env_set affect the running script immediately.

Command functions return a table with stdout, stderr, and exit_code so you can inspect output and success in one place; path and file helpers return plain strings, booleans, or tables. A few functions are platform-specific (resolve_shortcut, extract_icon are Windows-only; shell_execute maps to ShellExecuteW on Windows and xdg-open elsewhere), so guard them with os() or is_windows() when writing cross-platform code.

Common patterns

Run a command and branch on its exit code:

use plugin shell::{exec}

let result = exec("cargo build --release")
if result["exit_code"] == 0 {
  print("build ok")
} else {
  print("build failed:\n{result["stderr"]}")
}

Build a path, make sure its directory exists, then write to it:

use plugin shell::{path_join, mkdir, write_file, home_dir}

let dir = path_join([home_dir(), "reports"])
mkdir(dir)
let file = path_join([dir, "summary.txt"])
write_file(file, "generated by zolo\n")
print("wrote {file}")

Find every Zolo source file under a tree and report its size:

use plugin shell::{glob, file_size, path_filename}

let files = glob("src/**/*.zolo")
for _, path in files {
  print("{path_filename(path)}: {file_size(path)} bytes")
}

Run a shell command, return stdout/stderr/exit_code

Runs a shell command and returns a table with stdout, stderr, and exit_code. Use this when you need the full output of a command.

use plugin shell::{exec}

let result = exec("git log --oneline -5")
print(result["stdout"])
print("exit: {result["exit_code"]}")

Inspect both streams to surface a failure message:

use plugin shell::{exec}

let r = exec("ls /does-not-exist")
if r["exit_code"] != 0 {
  print("error: {r["stderr"]}")
}

Run a command, return only the exit code

Runs a command and returns only the exit code as an integer. Use this to check whether a command succeeded (0 = success).

use plugin shell::{exec_status}

let code = exec_status("cargo test")
if code == 0 {
  print("tests passed")
} else {
  print("tests failed with code {code}")
}

Run a command, return stdout as a table of lines

Runs a command and returns stdout as a table indexed by line number. Convenient for processing line-by-line output.

use plugin shell::{exec_lines}

let lines = exec_lines("ls -1")
for _, line in lines {
  print(line)
}

Run a command with extra environment variables

Runs a command with additional environment variables supplied as a table. Returns stdout, stderr, and exit_code.

use plugin shell::{exec_env}

let result = exec_env("printenv MY_VAR", #{"MY_VAR": "hello"})
print(result["stdout"])

Run a command in a specific working directory

Runs a command with its working directory set to dir. Returns stdout, stderr, and exit_code.

use plugin shell::{exec_in_dir}

let result = exec_in_dir("cargo build --release", "/home/user/myproject")
print(result["stdout"])

Chain multiple commands with pipes

Chains an array of commands with Unix pipes and returns stdout, stderr, and exit_code.

use plugin shell::{pipe}

let result = pipe(["ps aux", "grep rust", "wc -l"])
print("rust processes: {result["stdout"]}")

Count the lines in a file by chaining cat into wc:

use plugin shell::{pipe}

let r = pipe(["cat access.log", "wc -l"])
print("log lines: {r["stdout"]}")

Find the path to a program on PATH

Returns the full path to program if found on PATH, or nil if not found.

use plugin shell::{which}

let path = which("cargo")
if path != nil {
  print("cargo is at {path}")
}

Read an environment variable

Returns the value of the environment variable name, or nil if not set.

use plugin shell::{env_get}

let home = env_get("HOME")
print("home is {home}")

Fall back to a default when the variable is unset:

use plugin shell::{env_get}

let level = env_get("LOG_LEVEL")
if level == nil {
  level = "info"
}
print("log level: {level}")

Set an environment variable

Sets the environment variable name to value for the current process.

use plugin shell::{env_set}

env_set("DEBUG", "1")

Remove an environment variable

Removes the environment variable name from the current process.

use plugin shell::{env_remove}

env_remove("DEBUG")

List all environment variables

Returns a table of all current environment variables as key-value pairs.

use plugin shell::{env_list}

let vars = env_list()
for key, val in vars {
  print("{key}={val}")
}

Get the current working directory

Returns the current working directory as an absolute path string.

use plugin shell::{cwd}

print("working in: {cwd()}")

Change the current working directory

Changes the current working directory to path.

use plugin shell::{chdir, cwd}

chdir("/tmp")
print(cwd())

Get the user's home directory

Returns the user's home directory path, or nil if it cannot be determined.

use plugin shell::{home_dir}

print("home: {home_dir()}")

Get the system temporary directory

Returns the system temporary directory path.

use plugin shell::{temp_dir}

print("temp: {temp_dir()}")

Get the OS path separator character

Returns the OS-specific path separator (/ on Unix, \ on Windows).

use plugin shell::{path_separator}

print("separator: {path_separator()}")

Get the operating system name

Returns the operating system identifier string, e.g. "windows", "linux", or "macos".

use plugin shell::{os}

print("running on: {os()}")

Get the CPU architecture name

Returns the CPU architecture string, e.g. "x86_64" or "aarch64".

use plugin shell::{arch}

print("arch: {arch()}")

Check if running on Windows

Returns true if the current platform is Windows.

use plugin shell::{is_windows}

if is_windows() {
  print("on Windows")
}

Check if running on Linux

Returns true if the current platform is Linux.

use plugin shell::{is_linux}

if is_linux() {
  print("on Linux")
}

Check if running on macOS

Returns true if the current platform is macOS.

use plugin shell::{is_macos}

if is_macos() {
  print("on macOS")
}

Match file paths using a glob pattern

Returns a table of file paths matching the glob pattern. Supports *, **, and ? wildcards.

use plugin shell::{glob}

let files = glob("src/**/*.zolo")
for _, path in files {
  print(path)
}

Glob a flat directory for a single extension:

use plugin shell::{glob, path_stem}

let images = glob("assets/*.png")
for _, p in images {
  print("image: {path_stem(p)}")
}

Check if a path exists

Returns true if path exists (as a file or directory).

use plugin shell::{exists}

if exists("/etc/hosts") {
  print("hosts file found")
}

Check if a path is a regular file

Returns true if path exists and is a regular file.

use plugin shell::{is_file}

print(is_file("README.md"))

Check if a path is a directory

Returns true if path exists and is a directory.

use plugin shell::{is_dir}

print(is_dir("/tmp"))

Get a file's size in bytes

Returns the size of the file at path in bytes.

use plugin shell::{file_size}

let size = file_size("archive.zip")
print("size: {size} bytes")

Read a file's content as a string

Reads the entire content of the file at path and returns it as a string.

use plugin shell::{read_file}

let content = read_file("config.toml")
print(content)

Guard the read with exists so a missing file does not error:

use plugin shell::{exists, read_file}

if exists("notes.md") {
  print(read_file("notes.md"))
} else {
  print("no notes yet")
}

Write a string to a file

Writes content to the file at path, creating or overwriting it.

use plugin shell::{write_file}

write_file("output.txt", "Hello, world!")

Append a string to a file

Appends content to the end of the file at path, creating it if it does not exist.

use plugin shell::{append_file}

append_file("log.txt", "new log entry\n")

Create a directory (and parents)

Creates a directory at path, including all intermediate parent directories.

use plugin shell::{mkdir}

mkdir("build/output/assets")

Remove a directory recursively

Removes the directory at path and all its contents recursively.

use plugin shell::{rmdir}

rmdir("build/output")

Copy a file to another path

Copies the file from src to dst.

use plugin shell::{copy_file}

copy_file("config.toml", "config.toml.bak")

Move or rename a file

Moves or renames the file from src to dst.

use plugin shell::{move_file}

move_file("temp_output.txt", "final_output.txt")

Delete a file

Deletes the file at path.

use plugin shell::{remove_file}

remove_file("temp.txt")

List entries in a directory

Lists entries in the directory at path. Each entry is a table with name, is_dir, and size.

use plugin shell::{list_dir}

let entries = list_dir(".")
for _, entry in entries {
  print("{entry["name"]} - dir: {entry["is_dir"]}")
}

List only the subdirectories of a path:

use plugin shell::{list_dir}

let entries = list_dir("/home/user")
for _, entry in entries {
  if entry["is_dir"] {
    print("dir: {entry["name"]}")
  }
}

Recursively list all files in a directory

Recursively walks path and returns a flat table of all file paths found.

use plugin shell::{walk_dir}

let files = walk_dir("src")
for _, f in files {
  print(f)
}

Join path parts into a single path

Joins a table of path parts into a single path using the OS separator.

use plugin shell::{path_join}

let p = path_join(["home", "user", "documents", "file.txt"])
print(p)

Combine with cwd to build an absolute path under the working directory:

use plugin shell::{path_join, cwd}

let target = path_join([cwd(), "dist", "bundle.js"])
print(target)

Get the parent directory of a path

Returns the parent directory of path, or nil if there is no parent.

use plugin shell::{path_parent}

print(path_parent("/home/user/file.txt"))

Get the filename component of a path

Returns the final filename component of path, including the extension.

use plugin shell::{path_filename}

print(path_filename("/home/user/file.txt"))

Get the file extension of a path

Returns the file extension of path (without the leading dot), or nil.

use plugin shell::{path_extension}

print(path_extension("archive.tar.gz"))

Get the filename without its extension

Returns the filename without its extension.

use plugin shell::{path_stem}

print(path_stem("report.pdf"))

Resolve a path to its canonical absolute form

Resolves path to its canonical absolute path, resolving symlinks and .. components.

use plugin shell::{absolute_path}

print(absolute_path("../src"))

Open a file or URL with the OS shell verb

Opens a file or URL using the OS shell (ShellExecuteW on Windows, xdg-open on Linux). Returns a result code. verb, args, and cwd are optional.

use plugin shell::{shell_execute}

shell_execute("https://zolo-lang.dev", nil, nil, nil)

Resolve a Windows .lnk shortcut file

Resolves a Windows .lnk shortcut and returns a table with target, args, working_dir, description, icon_location, and icon_index. Windows-only.

use plugin shell::{resolve_shortcut}

let info = resolve_shortcut("C:\\Users\\user\\Desktop\\MyApp.lnk")
print(info["target"])

Extract an icon from a file as PNG bytes

Extracts the icon associated with a file and returns it as PNG bytes (the registered return type is any). size selects the icon resolution (16, 32, 48, 256). Windows-only.

use plugin shell::{extract_icon, write_file}

let png = extract_icon("C:\\Windows\\notepad.exe", 32)

List directory entries with metadata

Lists directory entries with rich metadata: name, full_path, is_shortcut, is_directory, size, and modified_unix.

use plugin shell::{read_directory_items}

let items = read_directory_items("C:\\Users\\user\\Desktop")
for _, item in items {
  print("{item["name"]} shortcut={item["is_shortcut"]}")
}

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

en