Built-in Commands¶
Endo provides a set of built-in commands that are executed directly by the shell, without spawning an external process. These builtins handle core shell operations, I/O, and environment management.
echo¶
Print arguments to standard output.
Syntax:
Description: Writes its arguments to stdout, separated by spaces, followed by a newline.
Example:
cd¶
Change the current working directory.
Syntax:
Description: Changes the shell's working directory. With no argument, changes to $HOME. Supports tilde expansion (~, ~user). Use cd - to switch to the previous working directory ($OLDPWD).
Example:
Tilde expansion for other users:
cd ~alice # go to alice's home directory
cd ~bob/Documents # go to bob's Documents folder
echo ~alice # prints the resolved path
On POSIX systems, ~username is resolved via the system user database (getpwnam). On Windows, Endo derives the path from the current user's USERPROFILE parent directory -- for example, if USERPROFILE is C:\Users\chris, then ~alice resolves to C:\Users\alice (if that directory exists). See Platform Differences for details.
pwd¶
Print the current working directory.
Syntax:
Description: Outputs the absolute path of the current working directory.
Example:
exit¶
Exit the shell.
Syntax:
Description: Terminates the shell with the given exit code. Defaults to 0 (success) if no code is provided.
Example:
export¶
Export an environment variable.
Syntax:
Description: Sets an environment variable and marks it for export to child processes. When called with just a name, exports an existing variable.
Example:
F#-style export is also supported:
set¶
Set a shell variable.
Syntax:
Description: Sets a shell variable. Unlike export, this does not export the variable to child processes.
Example:
unset¶
Unset a shell variable.
Syntax:
Description: Removes a variable from the shell environment.
Example:
read¶
Read input from the user or a file descriptor.
Syntax:
Description: Reads a line of input and splits it into variables using $IFS.
Flags:
| Flag | Description |
|---|---|
-p PROMPT | Display a prompt string before reading |
-r | Do not interpret backslash escapes |
-s | Silent mode (do not echo input, useful for passwords) |
-n COUNT | Read at most COUNT characters |
-t SECONDS | Timeout after SECONDS (returns failure if exceeded) |
-d DELIM | Use DELIM as the line delimiter instead of newline |
Example:
read -p "Enter your name: " name
echo "Hello, $name!"
read -s -p "Password: " password
read -n 1 -p "Continue? (y/n) " answer
true¶
Return a successful (zero) exit code.
Syntax:
Description: Always returns exit code 0. Useful in conditionals and loops.
Example:
false¶
Return a failure (non-zero) exit code.
Syntax:
Description: Always returns exit code 1. Useful in conditionals.
Example:
which¶
Locate a command in $PATH.
Description: which is a dual-mode builtin that searches the system $PATH for a given command. In shell mode (bare argument), it prints the resolved path to stdout and sets the exit code. In F# mode (quoted or parenthesized argument), it returns an Option<string> value suitable for pattern matching, pipelines, and functional composition.
The mode is determined by syntax: bare identifiers like which git use shell mode, while quoted strings like which "git" or parenthesized expressions like which (name) use F# mode.
Shell form¶
Syntax:
Searches $PATH for command and prints its absolute path to stdout. Returns exit code 0 on success or 1 if the command is not found.
Examples:
which git
# /usr/bin/git
which nonexistent
# (returns exit code 1)
# Use in a conditional
match which "cargo" with
| Some _ -> println "Rust toolchain available"
| None -> ()
F# form¶
Syntax:
Return type: Option<string>
Returns Some path if the program is found in $PATH, or None otherwise. The returned path is the fully resolved absolute path to the executable.
Examples:
# Pattern match on the result
match which "git" with
| Some path -> println path
| None -> println "git not found"
# With default operator
let gitPath = which "git" ?| "/usr/bin/git"
# In a pipeline
"ls" |> which |> fun opt -> match opt with | Some p -> println p | None -> println "not found"
# Bind to a variable
let result = which "cargo"
Tip
Use the shell form (which git) for quick interactive lookups. Use the F# form (which "git") when you need to branch on the result or compose it into a larger expression.
cat¶
Concatenate and display files.
Syntax:
Description: Reads files sequentially and writes their contents to standard output. If no files are given (or when FILE is -), reads from standard input.
When the output goes to a terminal, cat renders rather than dumps: markdown files become formatted documents, image files become Sixel graphics, and everything else is syntax-highlighted. When the output is redirected or piped, the file's bytes are written verbatim, so cat file > copy and cat file | grep x behave exactly as they always have.
Options:
| Option | Long form | Description |
|---|---|---|
-n | --number | Number all output lines |
-b | --number-nonblank | Number non-blank output lines (overrides -n) |
-s | --squeeze-blank | Suppress repeated empty output lines |
-E | --show-ends | Display $ at end of each line |
-T | --show-tabs | Display TAB characters as ^I |
-A | --show-all | Equivalent to -ET |
-r | --range START..END | Show only lines in the given range |
-c | --columns N | Target image width in terminal columns |
-R | --rows N | Target image height in terminal rows |
--indent N | Left margin for rendered markdown, in columns (default 1) | |
--raw | Disable all rendering (markdown, images, highlighting) | |
-h | --help | Display help and exit |
Markdown rendering¶
cat on a .md or .markdown file renders the document:
- Tables are drawn with box-drawing borders, honoring column alignment.
- Links become clickable via OSC 8 hyperlinks. Only absolute URIs are hyperlinked; relative paths (
LICENSE) and fragments (#install) are shown as styled text, since a terminal cannot resolve them. Autolinks (<https://example.com>,<user@example.com>) are hyperlinked too, but bare URLs in prose are not. - Titles use DEC double-width and double-height line attributes:
#headings are drawn double-height,##double-width. - Centered blocks follow the HTML that GitHub honors:
<div align="center">,<p align="center">,<h1 align="center">…<h6 align="center">, and the legacy<center>.align="left"andalign="right"work as well.<b>/<strong>,<i>/<em>and<br>are understood inside them. - Inline HTML
<a href="…">…</a>renders as a hyperlink and<img alt="…">as its alt text, anywhere in the document. HTML inside a code span or fenced block stays literal. - Images embed as Sixel graphics (see below).
Rendered documents carry a one-column left margin so the first word of each line does not sit against the terminal edge. --indent N changes it; --indent 0 removes it. The margin is subtracted from the width available to content, so centering and table widths account for it. Under the double-width titles a single indent cell occupies two columns, since DEC line attributes widen every cell on the line.
Rendering is suppressed by --raw, by redirecting or piping the output, and by any line-processing flag (-n, -b, -s, -E, -T, -r) — those ask for a literal view of the source text, which a rendered document cannot provide.
Inline images¶
An image alone on its line — written as  or <img src="logo.png"> — is decoded and drawn as a Sixel image. The source path is resolved relative to the document, not the working directory. An <img width="N"> attribute sets the width in pixels, clamped to the terminal width; images are never scaled up beyond their natural size.
Supported formats are exactly those cat accepts for image files: PNG, JPEG, GIF, BMP, TGA, PSD, HDR and PNM/PGM/PPM. SVG and WebP are not supported — the bundled decoder cannot read them, which matters because README badges are usually SVG. Animated GIFs show their first frame only.
An image falls back to rendering its alt text when the terminal lacks Sixel support, when the source is remote (https://…, data:…), when the file is missing or undecodable, or when its format is unsupported. Images that share a line with other text, or that appear inside a table cell or list item, always render as alt text.
Sixel support is detected once per session from the terminal's Primary Device Attributes (DA1) response. Set ENDO_SIXEL=0 to disable inline images without disabling the rest of the markdown rendering, or ENDO_SIXEL=1 to force them on.
Range syntax:
3..7— show lines 3 through 7..5— show lines 1 through 510..— show from line 10 to the end of the file
When -n or -b is combined with --range, line numbers reflect the original file positions (not re-numbered from 1).
Syntax highlighting is supported for C/C++ (and C-family languages such as JavaScript, TypeScript, Rust, Go), Python, Bash, CMake, JSON, YAML, x86 assembly, Git diffs, PowerShell (.ps1, .psm1, .psd1), Windows CMD/batch (.cmd, .bat), XML and XML-based dialects (.xml, .props, .csproj, .targets, .vcxproj, .xaml, .svg, …), INI (.ini), and Endo (.endo). A few well-known files are recognized by name rather than extension: .clang-format, .clang-tidy, and .endo-format are highlighted as YAML, and .editorconfig as INI.
Examples:
cat README.md # rendered: tables, links, titles, images
cat --indent 4 README.md # wider left margin
cat --raw README.md # the markdown source, verbatim
cat README.md | less # plain bytes, no escapes
cat file1.txt file2.txt > combined.txt
echo "hello" | cat
cat -n script.sh
cat --range 10..20 main.cpp
cat -nr 5..15 data.txt
cat logo.png # Sixel image
cat -c 40 logo.png # scaled to 40 columns wide
mkdir¶
Create directories.
Syntax:
Description: Creates the specified directories. By default, fails if the directory already exists or if parent directories are missing.
Options:
| Option | Description |
|---|---|
-p, --parents | Create parent directories as needed; no error if the directory already exists |
-v, --verbose | Print a message for each created directory |
-- | End of options; treat subsequent arguments as directory names |
Examples:
mkdir mydir
mkdir -p path/to/nested/dir
mkdir -pv project/src project/tests
mkdir -- -starts-with-dash
cp¶
Copy files and directories.
Syntax:
Description: Copies SOURCE to DEST, or multiple SOURCE(s) to an existing DIRECTORY. By default, overwrites existing destination files. Copying a directory requires the -r flag.
Options:
| Option | Description |
|---|---|
-r, -R, --recursive | Copy directories recursively |
-f, --force | Force overwrite; remove destination if needed |
-n, --no-clobber | Do not overwrite existing files |
-v, --verbose | Print each file as it is copied |
-- | End of options; treat subsequent arguments as file names |
Examples:
cp file.txt backup.txt
cp -r srcdir dstdir
cp -rv project/ /tmp/project-backup/
cp -n important.txt dest/
cp -- -starts-with-dash.txt dest.txt
cp a.txt b.txt c.txt target-directory/
mv¶
Move or rename files and directories.
Syntax:
Description: Moves SOURCE to DEST, or multiple SOURCE(s) to an existing DIRECTORY. If the destination is on a different filesystem, the file is copied and the source is removed. By default, overwrites existing destination files without prompting.
Options:
| Option | Description |
|---|---|
-f, --force | Do not prompt before overwriting |
-n, --no-clobber | Do not overwrite existing files |
-v, --verbose | Print each file as it is moved |
-i, --interactive | Prompt before overwriting |
-- | End of options; treat subsequent arguments as file names |
Examples:
mv file.txt renamed.txt
mv file.txt /tmp/
mv -v old.txt new.txt
mv -n important.txt dest/
mv -- -starts-with-dash.txt dest.txt
mv a.txt b.txt c.txt target-directory/
rm¶
Remove files and directories.
Syntax:
Description: Remove (unlink) the specified files. By default, does not remove directories. Use -r to remove directories and their contents recursively. Refuses to recursively remove /, ., or .. as a safety measure.
Options:
| Option | Description |
|---|---|
-f, --force | Ignore nonexistent files, never prompt |
-i | Prompt before every removal |
-r, -R, --recursive | Remove directories and their contents recursively |
-d, --dir | Remove empty directories |
-v, --verbose | Explain what is being done |
-- | End of options |
-h, --help | Display help |
Examples:
find¶
Search for files in a directory hierarchy.
Syntax:
Description: Recursively searches for files and directories matching the given criteria. If no path is given, the current directory is used. If no expression is given, all files are matched.
Options:
| Option | Description |
|---|---|
-maxdepth N | Descend at most N levels |
-mindepth N | Do not apply tests at levels less than N |
-print0 | Print entries separated by null instead of newline |
-h, --help | Display help |
Predicates:
| Predicate | Description |
|---|---|
-name PATTERN | Match filename against glob pattern |
-iname PATTERN | Like -name but case-insensitive |
-path PATTERN | Match full path against glob pattern |
-ipath PATTERN | Like -path but case-insensitive |
-type TYPE | Match file type: f (file), d (directory), l (symlink) |
-size [+\|-]N[c\|k\|M\|G] | Match file size (c=bytes, k=KiB, M=MiB, G=GiB) |
-mtime [+\|-]N | Match modification time in 24-hour periods |
-newer FILE | Match files newer than FILE |
-empty | Match empty files or directories |
Operators:
| Operator | Description |
|---|---|
-a, -and | Logical AND (implicit between predicates) |
-o, -or | Logical OR |
-not, ! | Logical NOT |
( expr ) | Group expressions |
Examples:
find . -name "*.cpp"
find src -type f -name "*.hpp"
find . -type f -size +1M
find . -name "*.o" -o -name "*.tmp"
find /tmp -maxdepth 2 -empty
grep¶
Search for patterns in files.
Syntax:
Description: Searches for lines matching a regular expression pattern. If no files are specified, reads from standard input. Returns exit code 0 if matches are found, 1 if no matches are found, and 2 if errors occurred.
Pattern options:
| Option | Description |
|---|---|
-e PATTERN | Use PATTERN for matching (repeatable for multiple patterns) |
-F | Interpret PATTERN as fixed strings, not regex |
-E | Interpret PATTERN as extended regex (default) |
-i | Ignore case distinctions |
-w | Match whole words only |
-x | Match whole lines only |
Output options:
| Option | Description |
|---|---|
-c | Print only a count of matching lines per file |
-l | Print only names of files with matches |
-L | Print only names of files without matches |
-n | Prefix each line with its line number |
-H | Print the filename for each match |
-h | Suppress the filename prefix |
-o | Print only the matching parts of lines |
-v | Invert match — select non-matching lines |
-q | Quiet mode — no output, exit code only |
-s | Suppress error messages about missing files |
Context options:
| Option | Description |
|---|---|
-A NUM | Print NUM lines of trailing context after each match |
-B NUM | Print NUM lines of leading context before each match |
-C NUM | Print NUM lines of context (before and after) |
File selection:
| Option | Description |
|---|---|
-r, -R | Recurse into directories |
-m NUM | Stop after NUM matches per file |
-I | Skip binary files |
--include=GLOB | Search only files matching GLOB |
--exclude=GLOB | Skip files matching GLOB |
--exclude-dir=DIR | Skip directories matching DIR |
--color=MODE | Colorize output (auto, always, never) |
--help | Display help |
Examples:
grep "TODO" src/*.cpp
grep -rn "error" src/
grep -i "pattern" file.txt
grep -c "match" *.log
grep -rl "deprecated" --include="*.hpp" src/
grep -v "^#" config.txt
sleep¶
Wait for a specified duration.
Syntax:
Description: Pauses execution for the given number of seconds. Supports decimal values.
Example:
timeout¶
Run a command with a time limit.
Syntax:
Description: Runs a command and terminates it if it does not complete within the given duration. By default, sends SIGTERM on timeout. Use -k to send SIGKILL after a grace period if the command does not respond to the initial signal.
Duration format: A number with optional suffix: s (seconds, default), m (minutes), h (hours), d (days). Decimal values are supported (e.g. 1.5m).
Options:
| Option | Description |
|---|---|
-s SIGNAL, --signal=SIGNAL | Signal to send on timeout (default: TERM) |
-k DURATION, --kill-after=DURATION | Send SIGKILL after grace period if still running |
--preserve-status | Return the command's exit status instead of 124 on timeout |
--foreground | Don't create a separate process group |
-v, --verbose | Diagnose to stderr when signal is sent |
-h, --help | Show help |
Exit codes:
| Code | Meaning |
|---|---|
| 124 | Command timed out |
| 125 | timeout itself failed |
| 126 | Command found but not executable |
| 127 | Command not found |
| 128+N | Command was killed by signal N |
Examples:
timeout 5 sleep 100
timeout 1.5m long-running-task
timeout -s KILL 10 command
timeout -k 2 30 long-running-cmd
kill¶
Send signals to processes or jobs.
Syntax:
Description: Sends a signal to one or more processes by PID, or to background jobs by job ID. The default signal is SIGTERM (15). Use %N to refer to job number N from the job table (see jobs).
Options:
| Option | Description |
|---|---|
-SIGNAL | Signal to send by name or number (e.g. -9, -TERM, -SIGKILL) |
-s SIGNAL | Signal to send (POSIX style) |
-l | List available signal names |
-h, --help | Show help |
Common signals:
| # | Name | Description |
|---|---|---|
| 1 | HUP | Hangup |
| 2 | INT | Interrupt (Ctrl+C) |
| 9 | KILL | Kill (cannot be caught) |
| 15 | TERM | Terminate (default) |
| 19 | STOP | Stop (cannot be caught) |
Examples:
pgrep¶
Print PIDs of processes matched by name or command-line pattern.
Syntax:
Description: Lists the process IDs of all running processes whose command name matches PATTERN, an ECMAScript regular expression. By default a substring search is performed and one PID is printed per line. Exits with status 0 if at least one process matched, 1 if none did.
Options:
| Option | Description |
|---|---|
-f | Match PATTERN against the full command line |
-x | Require an exact (anchored) match |
-i | Case-insensitive pattern match |
-v | Invert the match: select non-matching processes |
-c | Print only the count of matched processes |
-l | Print the process name along with the PID |
-n | Match only the newest (highest PID) process |
-o | Match only the oldest (lowest PID) process |
-u USER[,USER] | Only match processes owned by the listed users |
-d DELIM | Delimiter between printed PIDs (default: newline) |
-h, --help | Show help |
Portability: Matching runs against the platform's most reliable command field — the full argv[0] path on Linux, the (possibly truncated) command name on macOS, and the executable name (including .exe) on Windows. -f is accepted for CLI compatibility but targets the same field on all platforms.
Examples:
pidof¶
Print PIDs of running processes matching program names.
Syntax:
Description: Looks up the process IDs of all running processes whose program name equals one of the given PROGRAM names, and prints them space-separated on a single line, newest (highest PID) first. Unlike pgrep, matching is exact, not pattern-based. Exits with status 0 if at least one PID was found, 1 otherwise.
Options:
| Option | Description |
|---|---|
-s | Single shot: print at most one PID |
-q | Quiet: print nothing, only set the exit status |
-S SEP, --separator SEP | Separator between printed PIDs (default: space) |
-d SEP | Alias for -S (sysvinit compatibility) |
-o PID[,PID] | Omit the listed PIDs from the result (repeatable) |
-h, --help | Show help |
Portability: A PROGRAM name matches the process's command field verbatim or by its path basename. On Linux, the command field is the full argv[0] path (so both pidof sleep and pidof /usr/bin/sleep work); on macOS it is the (possibly truncated) command name; on Windows the comparison is case-insensitive and a trailing .exe is ignored (pidof notepad matches notepad.exe).
Examples:
jobs¶
List background jobs.
Syntax:
Description: Displays all background and stopped jobs with their job number, state, and command. The current job is marked with +, the previous job with -.
Job states:
| State | Description |
|---|---|
| Running | Job is currently executing |
| Stopped | Job was suspended (e.g. by Ctrl+Z) |
| Done | Job completed normally |
| Terminated | Job was killed by a signal |
Example:
fg¶
Bring a background job to the foreground.
Syntax:
Description: Resumes a stopped or background job in the foreground and waits for it to complete. If no job ID is given, uses the current job (marked with + in jobs output).
Examples:
bg¶
Resume a stopped job in the background.
Syntax:
Description: Resumes a stopped job in the background without waiting for it to complete. The job must be in the Stopped state (e.g. suspended with Ctrl+Z). If no job ID is given, uses the current job.
Examples:
# After pressing Ctrl+Z to suspend a job:
bg # resume current job in background
bg 1 # resume job 1 in background
wait¶
Wait for background jobs to complete.
Syntax:
Description: Waits for one or all background jobs to finish and returns their exit status. If a job ID is given, waits for that specific job. If no job ID is given, waits for all running background jobs.
Examples:
sleep 5 &
wait # wait for all background jobs
echo "all done"
sleep 10 &
wait 1 # wait for job 1 specifically
echo $? # prints the job's exit code
fetch¶
Perform HTTP requests.
Syntax:
Description: Makes an HTTP GET request to the given URL and outputs the response body to stdout.
Example:
Note
The fetch builtin currently supports basic GET requests. Additional HTTP methods and options are planned for a future release.
bind¶
Configure key bindings.
Syntax:
bind # List all bindings
bind -l, --list # List all bindings (same as no args)
bind KEY ACTION # Bind a key to an action
bind -r, --remove KEY # Remove a binding
bind --reset # Reset to default bindings
bind -h, --help # Show available actions and key format
Description: Manages the shell's key bindings at runtime. Changes take effect immediately. Keys are specified as modifier+key combinations (e.g. ctrl+a, alt+shift+f).
Modifiers: ctrl, alt (or meta), shift, super (or win, cmd)
Keys: a–z, enter, backspace, delete, tab, escape, up, down, left, right, home, end, pageup, pagedown, insert, space, f1–f12
Example:
# List all bindings
bind
# Bind Ctrl+Y to yank (paste from kill ring)
bind ctrl+y yank
# Remove a binding
bind -r ctrl+y
# Reset to defaults
bind --reset
# Show available actions grouped by category
bind --help
Available actions:
| Category | Actions |
|---|---|
| Movement | move-forward-char, move-backward-char, move-forward-word, move-backward-word, move-to-line-start, move-to-line-end, move-to-buffer-start, move-to-buffer-end, move-up, move-down, smart-move-to-line-start, smart-move-to-line-end |
| Editing | delete-char-backward, delete-char-forward, delete-word, delete-word-backward, delete-big-word-backward, kill-to-end, kill-to-start, transpose |
| Undo/Redo | undo, redo |
| Kill Ring | yank, yank-pop |
| Selection | select-all |
| Clipboard | cut, copy, paste |
| Control | submit, abort, insert-newline |
| History | history-prev, history-next |
See Configuration: Key Bindings for the full list of default bindings.
history¶
Display or manage command history.
Syntax:
Description: Displays the command history with numbered entries. When called without arguments, lists all entries. Supports viewing a subset, searching, and clearing.
Subcommands:
| Subcommand | Description |
|---|---|
| (none) | List all history entries, numbered |
N | List the last N entries |
search PATTERN | Search entries by prefix |
clear | Clear all history |
-h, --help | Display help |
Examples:
env¶
Get an environment variable (F# style).
Syntax (F# expression):
Description: Returns the value of an environment variable as an option<str>. Returns Some value if the variable is set, or None if it is not.
Example:
# Pattern match on the result
match (env "HOME") with
| Some dir -> println $"Home directory: {dir}"
| None -> println "HOME is not set"
# Use with Option default
let editor = (env "EDITOR") ?| "vi"
println $"Using editor: {editor}"
# Use with the ? operator in a function
let getHome () =
let home = (env "HOME")?
Ok home
Tip
For shell-style access to environment variables, use $VAR or ${VAR} substitution syntax instead. The env function is designed for F# expressions where you want type-safe Option handling.
source-env¶
Import environment variables from an external script.
Syntax:
Description: Runs an external script in its native interpreter, captures the resulting environment variables, and imports any new or changed variables into the current Endo shell session. The interpreter is selected based on the script's file extension.
Supported script types:
| Extension | Interpreter | Platforms |
|---|---|---|
.bat, .cmd | cmd.exe | Windows |
.ps1 | pwsh or powershell.exe | All (cross-platform) |
.sh | bash | All |
For .ps1 scripts, pwsh (PowerShell Core) is tried first. On Windows, powershell.exe (Windows PowerShell 5.x) is used as a fallback. On other platforms, pwsh must be installed.
Only variables that are new or changed compared to the current environment are imported. Existing variables that the script does not modify are left unchanged.
Example:
# Set up MSVC toolchain on Windows (PowerShell script)
source-env "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\Tools\Launch-VsDevShell.ps1"
# Set up MSVC toolchain on Windows (batch file with architecture)
source-env "C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvarsall.bat" "x64"
# Source a bash environment script
source-env /opt/tools/setup-env.sh
# Source a PowerShell script on Linux (requires pwsh)
source-env ./setup-toolchain.ps1
Return value: The exit code of the sourced script (0 on success).
source¶
Execute a script in the current shell context.
Syntax:
Description: Reads and executes commands from FILE in the current shell environment. Unlike running a script as a subprocess, variables, functions, and other state changes made by the sourced script persist after it completes. The . command is a POSIX-compatible alias for source.
Options:
| Option | Description |
|---|---|
-h, --help | Display help |
Examples:
Tip
Use source for Endo scripts (.endo files) that should modify the current shell environment. For importing environment variables from external shell scripts (bash, zsh, PowerShell), use source-env instead.
Note
You can also run .endo files directly in shell mode by typing their path: ./script.endo or path/to/script.endo. Endo detects the .endo extension and executes the file in-process instead of spawning it as an external command.
run_script¶
Execute an .endo script file in the current shell context (F# callable).
Syntax:
Description: Reads and executes an .endo script file in the current shell context, similar to source. Unlike source, run_script is an F# function and can be called from within expressions, pipelines, and function bodies. Returns the exit code as an integer.
Module imports within the executed script resolve relative to the script's location.
Examples:
# Execute a script
run_script "setup.endo"
# Check exit code
let result = run_script "tests/validate.endo"
if result <> 0 then println "validation failed"
rand¶
Generate a random integer.
Syntax:
Description: Generates a random integer. With no arguments, returns a random positive integer greater than zero. With two arguments, returns a random integer in the inclusive range [min, max].
Example:
# Random positive integer
let n = rand
print n
# Random integer between 1 and 6 (inclusive)
let roll = rand 1 6
print $"You rolled a {roll}"
# Use in a pipeline
rand 1 100 |> fun n -> print $"Random: {n}"
dirconfig¶
Manage directory configuration trust entries.
Syntax:
Description: Endo supports per-directory configuration files (.local-env.endo) that are sourced when you enter a directory. Because these files can execute arbitrary commands, they require explicit trust approval. The dirconfig command manages this trust database.
If no path is given, defaults to .local-env.endo in the current directory.
Subcommands:
| Subcommand | Description |
|---|---|
allow [path] | Trust and allow a directory config |
deny [path] | Deny a directory config |
revoke [path] | Remove the trust entry for a directory config |
list | List all registered directory config trust entries |
reload | Reload all directory configs |
Options:
| Option | Description |
|---|---|
-h, --help | Show help |
Examples:
dirconfig allow # trust .local-env.endo in current dir
dirconfig allow ~/project/.local-env.endo
dirconfig deny /tmp/.local-env.endo
dirconfig list
dirconfig revoke ~/old-project/.local-env.endo
dirconfig reload
whoami¶
Print the current username.
Syntax:
Description: Prints the effective username of the current user. Cross-platform: uses getpwuid(geteuid()) on POSIX and GetUserNameA() on Windows.
Example:
hostname¶
Print the system hostname.
Syntax:
Description: Prints the network hostname of the current machine.
Example:
date¶
Print or format the current date and time.
Syntax:
Description: Displays the current date and time. Supports custom format strings (strftime syntax), epoch timestamps, ISO 8601 output, and UTC mode.
Options:
| Option | Description |
|---|---|
-u, --utc | Use UTC instead of local time |
--epoch | Print seconds since Unix epoch |
--iso | Print in ISO 8601 format |
-f FMT, --format FMT | Use custom strftime format |
-d STRING, --date STRING | Display given date (supports @EPOCH) |
-h, --help | Display help |
Format specifiers: %Y (year), %m (month), %d (day), %H (hour), %M (minute), %S (second), %A (weekday), %B (month name), %Z (timezone).
Examples:
cal¶
Display a colorful calendar for a month or year.
Syntax:
Description: Renders a monthly or yearly calendar. With no arguments, shows the current month with today's date highlighted. MONTH YEAR selects a specific month (MONTH is 1-12); a single positional argument is treated as a year from 1-9999 and renders all 12 months in a 3×4 grid.
When stdout is a terminal and NO_COLOR is not set, cal emits ANSI color: today's date is highlighted, the month/year header is bold, and weekend columns are tinted. Color is suppressed automatically when output is piped or when --no-color is given.
Options:
| Option | Description |
|---|---|
-3, --three | Show previous, current, and next month side-by-side |
-y, --year | Show the entire current year |
-m, --monday | Start the week on Monday (ISO 8601, default) |
-s, --sunday | Start the week on Sunday |
-n, --no-color | Disable colorized output even on a terminal |
-h, --help | Display help |
Examples:
uname¶
Print system information.
Syntax:
Description: Prints system information. With no options, prints the kernel name.
Options:
| Option | Description |
|---|---|
-s | Print kernel name (default) |
-n | Print network node hostname |
-r | Print kernel release |
-m | Print machine hardware name |
-a | Print all information |
--help | Display help |
Examples:
nproc¶
Print the number of available processing units.
Syntax:
Description: Prints the number of processing units (CPU cores/threads) available on the system. Cross-platform: uses std::thread::hardware_concurrency() on all supported platforms (Linux, macOS, Windows). Compatible with Linux's /usr/bin/nproc.
Options:
| Option | Description |
|---|---|
--all | Print the number of installed processors (default) |
--ignore=N | Exclude N processing units (result is at least 1) |
-h, --help | Display help |
Examples:
basename¶
Strip directory and suffix from pathnames.
Syntax:
Description: Strips the directory portion from a pathname, leaving just the filename. If a SUFFIX is provided and the filename ends with it, the suffix is removed.
Examples:
basename /usr/local/bin/endo
# endo
basename /usr/local/file.txt .txt
# file
basename /usr/local/
# local
dirname¶
Strip last component from pathname.
Syntax:
Description: Strips the last component from a pathname, returning the directory portion. Returns . if the path contains no directory separators.
Examples:
realpath¶
Resolve to absolute canonical path.
Syntax:
Description: Resolves each PATH to an absolute canonical path by expanding symlinks and removing . and .. components. Fails if the path does not exist.
Examples:
touch¶
Create files or update timestamps.
Syntax:
Description: Updates the modification timestamp of each FILE. Creates the file if it does not exist (unless -c is given).
Options:
| Option | Description |
|---|---|
-c, --no-create | Do not create files that don't exist |
-h, --help | Display help |
Examples:
ln¶
Create links between files.
Syntax:
ln [OPTIONS] TARGET # link in the current directory, named after TARGET
ln [OPTIONS] TARGET LINK_NAME # create LINK_NAME as a link to TARGET
ln [OPTIONS] TARGET... DIRECTORY # create links to each TARGET inside DIRECTORY
Description: Creates a link to TARGET. By default, creates a hard link; use -s for a symbolic link.
Operand handling follows GNU ln:
- With a single TARGET, the link is created in the current directory, named after TARGET's basename (e.g.
ln -s build/clang-debug/compile_commands.jsoncreates./compile_commands.json). - If LINK_NAME is an existing directory, the link is created inside it, named after TARGET's basename.
- With more than two operands, the last must be an existing directory and a link to each preceding TARGET is created inside it.
Options:
| Option | Description |
|---|---|
-s | Create a symbolic link |
-f | Remove an existing destination first (including a dangling symlink) |
-n, --no-dereference | Treat a symlink at the destination as a normal file (replace it rather than follow into it) |
-t, --target-directory=DIR | Create all links inside DIR |
-v | Explain what is being done |
--help | Display help |
Examples:
ln -s /usr/bin/python3 python
ln original.txt hardlink.txt
ln -sf newtarget existing-link # replaces existing-link, even if dangling
ln -sf build/clang-debug/compile_commands.json # creates ./compile_commands.json
ln -s target.txt some-directory # creates some-directory/target.txt
ln -s -t bin app1 app2 app3 # links app1..app3 inside bin/
mktemp¶
Create a temporary file or directory.
Syntax:
Description: Creates a temporary file (or directory with -d) with a unique name in the system temp directory. Prints the path to stdout.
Options:
| Option | Description |
|---|---|
-d | Create a directory instead of a file |
-p DIR | Use DIR as the base directory |
--help | Display help |
Examples:
head¶
Output the first lines of files.
Syntax:
Description: Prints the first N lines of each FILE to stdout. If no FILE is given (or FILE is -), reads from standard input. Default is 10 lines.
Options:
| Option | Description |
|---|---|
-n NUM | Output the first NUM lines (default: 10) |
-h, --help | Display help |
Examples:
tail¶
Output the last lines of files.
Syntax:
Description: Prints the last N lines of each FILE to stdout. If no FILE is given (or FILE is -), reads from standard input. Default is 10 lines.
Options:
| Option | Description |
|---|---|
-n NUM | Output the last NUM lines (default: 10) |
-f | Follow: output appended data as the file grows |
-h, --help | Display help |
Examples:
wc¶
Count lines, words, and characters.
Syntax:
Description: Counts lines, words, and characters in each FILE. If no FILE is given, reads from standard input. With no options, prints all three counts.
Options:
| Option | Description |
|---|---|
-l | Print line count |
-w | Print word count |
-c | Print character count |
--help | Display help |
Examples:
sort¶
Sort lines of text.
Syntax:
Description: Sorts lines from the given FILEs (or standard input) and writes the result to standard output.
Options:
| Option | Description |
|---|---|
-r | Reverse the sort order |
-n | Compare according to string numerical value |
-u | Output only unique lines |
-k FIELD | Sort by field number (whitespace-delimited) |
--help | Display help |
Examples:
sort names.txt
echo "cherry\napple\nbanana" | sort
# apple
# banana
# cherry
sort -rn scores.txt
sort -k 2 data.txt
uniq¶
Filter adjacent duplicate lines.
Syntax:
Description: Filters out adjacent duplicate lines from FILE (or standard input). Input should typically be sorted first for best results.
Options:
| Option | Description |
|---|---|
-c | Prefix lines with occurrence count |
-d | Only print duplicate lines |
-i | Ignore case when comparing |
--help | Display help |
Examples:
cut¶
Extract fields or characters from lines.
Syntax:
Description: Extracts selected fields or character ranges from each line of FILE (or standard input).
Options:
| Option | Description |
|---|---|
-d DELIM | Use DELIM as the field delimiter (default: tab) |
-f FIELDS | Select fields (e.g. 1, 1,3, 1-3) |
-c CHARS | Select characters (e.g. 1-5, 3) |
--help | Display help |
Examples:
echo "hello:world" | cut -d : -f 1
# hello
echo "abcdef" | cut -c 1-3
# abc
cut -d , -f 2,3 data.csv
tr¶
Translate or delete characters.
Syntax:
Description: Translates, squeezes, or deletes characters from standard input, writing to standard output. Character ranges like a-z and A-Z are expanded.
Options:
| Option | Description |
|---|---|
-d | Delete characters in SET1 (no translation) |
-s | Squeeze repeated output characters in SET2 |
--help | Display help |
Examples:
echo "hello world" | tr a-z A-Z
# HELLO WORLD
echo "hello" | tr -d l
# heo
echo "aabbcc" | tr -s a-z
# abc
tee¶
Read from stdin, write to stdout and files.
Syntax:
Description: Reads from standard input and writes to both standard output and one or more files simultaneously. Useful for capturing pipeline output while still seeing it.
Options:
| Option | Description |
|---|---|
-a | Append to files instead of overwriting |
-h, --help | Display help |
Examples:
echo "hello" | tee output.txt
echo "data" | tee -a log.txt
echo "test" | tee file1.txt file2.txt
echo "quiet" | tee /dev/null # portable: discards output on Linux, macOS, and Windows
Portability: The path /dev/null is accepted on all platforms. On Windows it is transparently mapped to the native NUL device. See Platform Differences → File Paths for details.