Skip to content

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:

echo [arguments...]

Description: Writes its arguments to stdout, separated by spaces, followed by a newline.

Example:

echo "Hello, World!"
echo "The value is" $x

cd

Change the current working directory.

Syntax:

cd [directory]
cd -

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:

cd /tmp
cd ~
cd ~/projects/endo
cd -          # returns to the previous directory

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:

pwd

Description: Outputs the absolute path of the current working directory.

Example:

pwd
# /home/alice/projects

exit

Exit the shell.

Syntax:

exit [code]

Description: Terminates the shell with the given exit code. Defaults to 0 (success) if no code is provided.

Example:

exit
exit 1

export

Export an environment variable.

Syntax:

export NAME=VALUE
export NAME

Description: Sets an environment variable and marks it for export to child processes. When called with just a name, exports an existing variable.

Example:

export PATH="/usr/local/bin:$PATH"
export EDITOR=nvim

F#-style export is also supported:

let export MY_VAR = "value"

set

Set a shell variable.

Syntax:

set NAME VALUE

Description: Sets a shell variable. Unlike export, this does not export the variable to child processes.

Example:

set greeting "hello"
echo $greeting

unset

Unset a shell variable.

Syntax:

unset NAME

Description: Removes a variable from the shell environment.

Example:

unset MY_VAR

read

Read input from the user or a file descriptor.

Syntax:

read [options] [variable...]

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:

true

Description: Always returns exit code 0. Useful in conditionals and loops.

Example:

while true do
    echo "loop"
    break
end

false

Return a failure (non-zero) exit code.

Syntax:

false

Description: Always returns exit code 1. Useful in conditionals.

Example:

if false then println "unreachable"

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:

which command

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:

which "command"
which (expr)

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:

cat [OPTIONS] [FILE...]

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 output goes to a terminal, syntax highlighting is applied automatically based on the file extension.

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
-h --help Display help and exit

Range syntax:

  • 3..7 — show lines 3 through 7
  • ..5 — show lines 1 through 5
  • 10.. — 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).

Examples:

cat README.md
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

mkdir

Create directories.

Syntax:

mkdir [-pv] [--parents] [--verbose] [--] directory...

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:

cp [-rfnvR] [--recursive] [--force] [--no-clobber] [--verbose] [--] source... dest

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:

mv [-fnvi] [--force] [--no-clobber] [--verbose] [--interactive] [--] source... dest

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:

rm [OPTIONS] FILE...

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:

rm file.txt
rm -f nonexistent.txt
rm -rf build/
rm -rv old-project/
rm -- -starts-with-dash.txt

find

Search for files in a directory hierarchy.

Syntax:

find [PATH...] [EXPRESSION]

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:

grep [OPTIONS] PATTERN [FILE...]

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:

sleep seconds

Description: Pauses execution for the given number of seconds. Supports decimal values.

Example:

sleep 1
sleep 0.5
echo "done"

timeout

Run a command with a time limit.

Syntax:

timeout [OPTIONS] DURATION COMMAND [ARG...]

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:

kill [-SIGNAL | -s SIGNAL] PID|%JOB ...
kill -l

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:

kill 1234
kill -9 1234
kill -TERM 1234
kill %1
kill -s USR1 5678
kill -l

jobs

List background jobs.

Syntax:

jobs

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:

sleep 100 &
sleep 200 &
jobs
# [1]+ Running   sleep 100 &
# [2]- Running   sleep 200 &

fg

Bring a background job to the foreground.

Syntax:

fg [job_id]

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:

sleep 100 &
fg          # bring the current job to foreground
fg 2        # bring job 2 to foreground

bg

Resume a stopped job in the background.

Syntax:

bg [job_id]

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:

wait [job_id]

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:

fetch URL

Description: Makes an HTTP GET request to the given URL and outputs the response body to stdout.

Example:

fetch https://api.github.com/zen

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: az, enter, backspace, delete, tab, escape, up, down, left, right, home, end, pageup, pagedown, insert, space, f1f12

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, 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:

history [N | search PATTERN | clear]

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:

history
history 20
history search git
history clear

env

Get an environment variable (F# style).

Syntax (F# expression):

env "VARIABLE_NAME"

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:

source-env <script-path>
source-env <script-path> <args...>

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:

source FILE [ARGS...]
. FILE [ARGS...]

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:

source ~/.config/endo/utils.endo
. ./setup-project.endo

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:

run_script "path/to/file.endo"

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:

rand
rand <min> <max>

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:

dirconfig <subcommand> [path]

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:

whoami

Description: Prints the effective username of the current user. Cross-platform: uses getpwuid(geteuid()) on POSIX and GetUserNameA() on Windows.

Example:

whoami
# alice

hostname

Print the system hostname.

Syntax:

hostname

Description: Prints the network hostname of the current machine.

Example:

hostname
# my-laptop

date

Print or format the current date and time.

Syntax:

date [OPTIONS]
date +FORMAT

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:

date
date --epoch
date --iso
date +%Y-%m-%d
date -u --iso
date -d @1700000000

cal

Display a colorful calendar for a month or year.

Syntax:

cal [OPTIONS]
cal [OPTIONS] YEAR
cal [OPTIONS] MONTH YEAR

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:

cal
cal 4 2026
cal 2026
cal -3
cal -s 4 2026
cal --no-color 2026 > year.txt

uname

Print system information.

Syntax:

uname [OPTIONS]

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:

uname
# Linux
uname -a
# Linux my-laptop 6.8.0-generic x86_64
uname -sm
# Linux x86_64

nproc

Print the number of available processing units.

Syntax:

nproc [OPTIONS]

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:

nproc
# 8

nproc --ignore=2
# 6

# Use in command substitution
let cores = $(nproc)

basename

Strip directory and suffix from pathnames.

Syntax:

basename PATH [SUFFIX]

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:

dirname PATH

Description: Strips the last component from a pathname, returning the directory portion. Returns . if the path contains no directory separators.

Examples:

dirname /usr/local/bin/endo
# /usr/local/bin
dirname file.txt
# .
dirname /file.txt
# /

realpath

Resolve to absolute canonical path.

Syntax:

realpath PATH...

Description: Resolves each PATH to an absolute canonical path by expanding symlinks and removing . and .. components. Fails if the path does not exist.

Examples:

realpath ./README.md
# /home/alice/projects/endo/README.md
realpath ../other-project

touch

Create files or update timestamps.

Syntax:

touch [OPTIONS] FILE...

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:

touch newfile.txt
touch -c existing-only.txt
touch a.txt b.txt c.txt

ln

Create links between files.

Syntax:

ln [OPTIONS] TARGET LINK_NAME

Description: Creates a link from LINK_NAME to TARGET. By default, creates a hard link. Use -s for symbolic links.

Options:

Option Description
-s Create a symbolic link
-f Remove existing destination file
-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

mktemp

Create a temporary file or directory.

Syntax:

mktemp [OPTIONS]

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:

mktemp
# /tmp/tmp.a8Kx3mZq9p
mktemp -d
# /tmp/tmp.b7Lw2nYr8q
mktemp -p /var/tmp

Output the first lines of files.

Syntax:

head [OPTIONS] [FILE...]

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:

head file.txt
head -n 5 file.txt
echo "line1\nline2\nline3" | head -n 2

tail

Output the last lines of files.

Syntax:

tail [OPTIONS] [FILE...]

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:

tail file.txt
tail -n 5 file.txt
echo "line1\nline2\nline3" | tail -n 2
tail -f /var/log/syslog

wc

Count lines, words, and characters.

Syntax:

wc [OPTIONS] [FILE...]

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:

wc file.txt
echo "hello world" | wc -w
# 2
echo "one\ntwo\nthree" | wc -l
# 3

sort

Sort lines of text.

Syntax:

sort [OPTIONS] [FILE...]

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:

uniq [OPTIONS] [FILE]

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:

sort names.txt | uniq
sort names.txt | uniq -c
echo "a\na\nb\na" | uniq
# a
# b
# a

cut

Extract fields or characters from lines.

Syntax:

cut [OPTIONS] [FILE...]

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:

tr [OPTIONS] SET1 [SET2]

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:

tee [OPTIONS] [FILE...]

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.