The Terminal Guide

Every terminal command a Copal machine carries on purpose: 288 of them. What each is for, why it is here, the package it came in, how to use it, and the parts people get wrong.

Facts read from Alpine 3.24.1 (aarch64) on 2026-09-24; 274 commands have written notes so far, the rest their facts and man page. Every page in man on a Copal machine is here too. How it is written, checked against a running machine: the lab report.

Copal

copal The installer, on the machine itself: re-run any stage, update Copal, and see what is installed.

Copal · Copal's own · stage 3 · Move the root filesystem onto the card, or a disk of its own

On Copal: Stage 3 leaves this copy on every Copal machine, so the whole install -- eighteen stages -- can be re-run, one stage or all of them, and updated from the repository without the Mac.

Use

With no arguments it shows the stage menu. --stage N re-runs chosen stages; -U updates Copal's scripts from the repository (or from a local checkout); --check says whether an update exists. Updating changes what the stages will do; it does not run them. copal fleet is the fleet console.

Examples

copalthe stage menu
copal --checkis there a newer Copal?
doas copal -Uupdate from the repository
doas copal --stage 17re-run one stage (the desktop)
doas copal --stage 12,18 --autore-run two, answering for you
doas copal -U --from ~/code/copal && doas copal --stage 17 --autotest a local change
copal --versionwhat is installed, and from where
copal fleet lsthe fleet console: what is out there

Options

--stage N,...
run only these stages (add --auto to answer their questions)
--auto
every stage, unattended, resuming across reboots
-U [REF]
update from the repository; REF a branch, tag or commit
-U --from PATH
update from a checkout on this machine
--check [REF]
whether an update is available; changes nothing
--version
the installed version and its source
fleet VERB ...
the fleet console, from the checkout in ~/code/copal

Notes

  • Every stage is written to be run again: a re-run repairs or updates what it set up and leaves the rest alone.
  • An update keeps the previous copy as copal-init.sh.bak.
  • -U REF pins a version: a tag or commit goes back to an older Copal.
  • copal fleet runs tools/copal-fleet.sh from the checkout in ~/code/copal (or $COPAL_CHECKOUT), because the console needs the checkout around it. On the Mac or Linux host that holds the fleet's authority, make install-fleet in the checkout adds the same command.

See also copal-store, copal-config, copal-code

copal-apps Copal Apps: the window for browsing Copal's programs by shelf, installing them, and watching installs happen.

Copal · Copal's own · stage 18 · The Copal Store, and OpenShot compiled

On Copal: The graphical face of copal-store. It never installs anything itself and never needs root: Install opens a terminal running doas copal-store install, and the window follows the progress. At the full monty's first login it opens on the slideshow of the queued programs arriving.

Use

Open it from the menu or the command line. Shelves on the left, programs with their status in the middle, one program in full on the right: its picture, two sentences, where it comes from and how it installs. While an install runs, it shows each program arriving with three progress bars.

Examples

copal-appsthe shelves and programs
copal-apps gimpopened on one program
copal-apps --progressthe install running now, as a slideshow
copal-apps --followthe slideshow, only if something is installing

Options

ID
open on that program
--progress
the running install's slideshow: the run, the program, the step
--follow
the same, but only when an install is queued or running

Notes

  • Everything it shows comes from copal-store (copal-store rows, copal-store playbook ID) and the event stream it writes to /var/log/copal/events: the terminal and the window always agree.
  • Pictures are the gallery's, fetched once into ~/.cache/copal-apps; a program without one shows its icon.
  • It needs a desktop (GTK); on a console, copal-store alone gives the same shelves as terminal menus.

See also copal-store, copal-install, copal-menu

copal-audio-start Start the sound server -- PipeWire, WirePlumber and the PulseAudio shim -- for this login.

Copal · Copal's own · stage 10 · Wireless, audio, capture and disks

On Copal: On Copal there is no systemd to start PipeWire per user, and it must not run as a system service. This starts the three parts once per session, skipping any already running, and does nothing at all on a machine without PipeWire.

Use

The i3 session runs it at startup. Run it by hand when a program says there is no sound server; it is safe to run again.

Examples

copal-audio-startstart whatever is missing
wpctl statusthen see the devices
tail $XDG_RUNTIME_DIR/copal-audio.logwhat the servers said

Options

Notes

  • It starts pipewire, then wireplumber (the session manager, which connects devices) and pipewire-pulse (so PulseAudio programs play), each only if installed and not already running for your user.
  • Their output goes to copal-audio.log in $XDG_RUNTIME_DIR (or /tmp), which is cleared at reboot.
  • Stage 10 installs PipeWire and writes this; the i3 session's startup file is what calls it.

See also wpctl, pipewire, pactl

copal-autologin What tty1 runs instead of the login prompt when the desktop starts at boot.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Autologin without a display manager: getty skips the name, this logs the admin user straight in. It also raises the memory-lock and real-time limits audio programs want, which nothing else on Copal can do, because logins here do not go through PAM.

Use

You do not run it. Stage 4 offers to start the desktop at boot; saying yes writes this and points tty1 at it in /etc/inittab.

Examples

grep tty1 /etc/inittabis autologin on?
doas rm /etc/copal/autostart-desktop # stop the desktop starting itself
ls /etc/inittab.bakthe inittab from before autologin

Options

Notes

  • The inittab line is getty -n -l /usr/local/bin/copal-autologin; it runs login -f for the admin user, so no password is asked on tty1. That is the point, and also the cost: whoever is at the keyboard is in.
  • It sets ulimit -l unlimited (locked memory, which keeps Ardour's and JACK's buffers out of swap) and ulimit -r 95 (real-time priority); the desktop inherits both.
  • After logging in, ~/.profile waits five seconds and runs copal-session; Ctrl-C in those seconds gives you a shell instead.
  • Deleting /etc/copal/autostart-desktop stops the desktop starting at boot, but the autologin stays: tty1 logs in to a shell. Undoing that means putting tty1's getty line in /etc/inittab back.

See also copal-session, getty, ulimit

copal-bar Start the desktop's bar and widgets with whichever shell the machine has: quickshell, else waybar.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: The theme's bar is written for quickshell, which Alpine does not package, so waybar stands in. copal-bar is the one place that decides, and prefers quickshell: install it and the next login uses the real thing, with nothing else changed.

Use

The session starts it; you run it by hand only to restart a bar that has gone. It starts the bar and the desktop widgets.

Examples

copal-bar &start the bar again, after it crashed
pkill -x waybar; copal-bar &restart it after editing its config

Options

Notes

  • The waybar configuration is in ~/.config/waybar; copal-theme rewrites its colours, so keep your own changes to layout and modules.
  • If neither shell is installed it says so where it will be seen, rather than leaving a desktop with no bar and no explanation.

See also copal-widgets, copal-theme

copal-build Compile the checkouts in ~/code and install what they make into ~/.local/bin, by the shape of each project.

Copal · Copal's own · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts

On Copal: "Built" should mean "installed": on PATH, in the menus, with a man page. copal-build reads each checkout's shape -- CMake, Cargo, Go, npm, or a cc65 Makefile -- and builds it the way that shape builds, so a fork or a project it has never heard of works the same.

Use

With no argument it builds every checkout in ~/code; name some to build only those. list shows each checkout's shape and whether what it made is on PATH.

Examples

copal-buildeverything in ~/code
copal-build staticstream ascittyjust these
copal-build listshapes, and what each made
copal-build clean birdshotdelete its build directory

Options

(none)
build every checkout
NAME...
build only these (directory names under ~/code)
list
each checkout, its shape, and the programs it made
clean NAME...
delete build/, native/build/ and target/; keep the checkout
-h, --help
the usage

Notes

  • Programs go to ~/.local/bin, which is on PATH from ~/.profile. Each gets a menu entry, and, from its README, a man page in ~/.local/share/man (man ytq), by copal-readme-man.
  • It never modifies a tracked file, because that would make every later git pull fail: npm uses ci where there is a lockfile, and a Plus/4 program uses its committed .prg and .d64 instead of recompiling. COPAL_BUILD_PLUS4=1 recompiles anyway (needs cc65).
  • Parallel jobs are the CPU count, capped at one per 512 MB of memory, so a small board does not swap.
  • copal itself is not built: it is a script (make redeploy in ~/code/copal). A checkout with none of the shapes is left alone.
  • COPAL_CODE and COPAL_PREFIX change ~/code and ~/.local.

See also copal-code, copal-readme-man, cargo, cmake

copal-camera Open the camera application, whichever one this machine has.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: One answer to "the camera", asked from three places -- the Camera entry in copal-menu, Super+Shift+B on both desktops, and the camera role in a copal-desk layout. Birdshot first, from ~/code; then other camera programs.

Use

Run it, or press Super+Shift+B; it opens the first camera program it finds: birdshot's window, else birdshot's browser viewfinder, else another installed camera application. --which says which, and opens nothing.

Examples

copal-cameraopen the camera
copal-camera --whichprint the command it would run
CAMERA=cheese copal-camerause another program, once

Options

--which
print the command it would run; exit 1 if there is none

Notes

  • $CAMERA overrides the choice, as $BROWSER does for the browser: set it in ~/.profile.local and every place that opens "the camera" follows.
  • Birdshot is one of the checkouts stage 7 builds into ~/.local/bin; copal-camera looks there even when the session did not read ~/.profile.

See also birdshot, copal-desk

copal-center One window listing the whole catalogue, installed or not, with the action for each.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+Shift+C: the catalogue at a glance. It opens Copal Apps where that exists, and the store's own window where it does not.

Use

Open it with Super+Shift+C or by name. Each row is a program with its status and section; choosing one runs it if installed, or installs it.

Examples

copal-centerthe catalogue window

Options

Notes

  • It is the older window of the two; Copal Apps (copal-apps) is the richer one, and copal-center hands over to it where it is installed.

See also copal-apps, copal-store, copal-install

copal-clip One clipboard, one set of keys, every window -- with a history, and a bridge to the VM host.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+C, Super+X and Super+V copy, cut and paste in every program, terminal included, the way Cmd-C does on a Mac. It keeps a clipboard history, and in a VM shares the clipboard with the host.

Use

The desktop binds the keys; you rarely run it by name. From a shell, store puts text on the clipboard and show prints it, which makes it the pipe between the clipboard and commands.

Examples

echo hello | copal-clip storeput text on the clipboard
copal-clip showprint the clipboard
copal-clip show | wc -wuse it in a pipeline
copal-clip historypick an earlier entry (Super+Ctrl+V)

Options

copy / cut / paste
the Super+C / Super+X / Super+V actions
history
choose from the clipboard history
store
put stdin on the clipboard
show
print the clipboard
watch
record the history (the session starts this)
bridge
share the clipboard with the VM host (the session starts this)

Notes

  • In a UTM or QEMU guest, copy and paste with the Mac works only while copal-clip bridge and spice-vdagent are running; both are started from hyprland.conf. If it stops working, check those two first.
  • The history keeps the last 100 entries, in ~/.cache/copal/clipboard; delete that folder to clear it.

See also wl-copy, ytq

copal-code Keep the source checkouts in ~/code: clone what is listed, pull what is there, then build it all.

Copal · Copal's own · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts

On Copal: A Copal machine arrives ready to work on its own projects. The list of repositories lives on the boot partition, where you can edit it from any computer before the card is even booted; this makes ~/code match it, and hands over to copal-build.

Use

Run it as yourself, with no argument: it clones anything listed that is missing, pulls (fast-forward only) anything that is there, and builds. add and rm edit the list and need doas.

Examples

copal-codeclone, pull, build
copal-code listthe list, and what is on disk
doas copal-code add https://github.com/you/project
copal-codethen clone it, as yourself
doas copal-code rm projectoff the list; the checkout stays
COPAL_NO_BUILD=1 copal-codeclone and pull, build later

Options

(none), sync
clone what is missing, pull what is there, then copal-build
list
each listed repository, and whether it is cloned
add URL...
add to the list (needs doas)
rm NAME...
remove from the list (needs doas); keeps the checkout
path
where the list is

Notes

  • The list is copal-repos on the boot partition (/boot), one URL per line, # for comments.
  • ~/code/copal, the repository the machine was built from, is always included and cannot be removed; repoint it with git remote set-url.
  • Cloning tries SSH first, without prompting, and falls back to HTTPS; a machine with no SSH key yet still gets its checkouts. copal-guide code explains adding a key.
  • A pull never forces: a checkout with local changes is warned about and left alone. A directory in the way that is not a checkout is skipped.
  • Machines installed before 24 September 2026 have the Yodacon builder under this name; running stage 7 again installs this one, and the builder as copal-yodacon.

See also copal-build, git, copal-guide

copal-config System settings for Copal: users, host name, time zone, keyboard, SSH, services, boot and storage.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: raspi-config's job, done with Copal's own tools: the settings a Pi owner changes, in one place, in a window on the desktop or in the terminal on a console.

Use

Run it; it opens a window where there is a display and terminal menus where there is not. Choose a screen, change a setting. Most settings write to /etc, so it asks for doas when it needs to.

Examples

copal-configthe settings, in a window or the terminal
copal-config --tuithe terminal menus, even on a desktop

Options

--tui
the terminal interface, even with a display
--help
the usage

Notes

  • Its screens: users (add one, groups), hostname, timezone, keymap, ssh, services (what starts at boot), boot, storage, and about.
  • Each screen uses the same tools a shell would -- setup-timezone, rc-update, copal-ssh -- so a change made here and one made by hand agree.
  • It works with GTK (yad), curses (dialog), or plain prompts, whichever the machine has.

See also copal-ssh, setup-alpine, rc-update

copal-debug Turn on Copal's debug collection: one folder, /var/log/copal, holding everything worth reading about a fault.

Copal · Copal's own · written on every run of the installer

On Copal: Off by default, because on a working machine the extra writes buy nothing. When something is wrong, one command gathers a snapshot of the machine and links to every relevant log in one place -- readable over SSH, or bundled into one file to send to someone.

Use

doas copal-debug on 1d starts collecting and switches itself off after a day. copal-debug alone says whether it is on and what it has gathered. bundle makes a .tar.gz to copy off the machine.

Examples

copal-debugon or off, and what is collected
doas copal-debug on 1dcollect for a day, then stop
doas copal-debug collectrefresh the snapshot now
doas copal-debug bundleone archive in /tmp, ready for scp
doas copal-debug offstop; keep what is there
doas copal-debug purgedelete the collection
COPAL_DEBUG=1 copal-startxdebug for one command only

Options

status
whether it is on, and what is in the folder (the default)
on [TIME]
start collecting; TIME (1d, 12h, 30m, or seconds) ends it
off
stop collecting, leave the folder
collect
refresh the snapshot
bundle
tar the folder, links resolved, into /tmp
purge
delete /var/log/copal
expire
switch off if the deadline has passed (cron runs this)

Notes

  • The folder holds sysinfo.txt (kernel, consoles, graphics, input, gettys, services, which Copal), dmesg.log, and links to the install transcript, the system log, Xorg's log and the last desktop session. A broken link is a finding: xorg.log pointing nowhere means X never started.
  • COPAL_DEBUG=1 or =0 in the environment overrides the switch for one command. The switch itself is the file /etc/copal/debug.
  • With debug on, copal-startx keeps ten session logs instead of two.

See also copal-logs, copal-startx, copal-gpu

copal-desk Put the workspaces into a known shape in one step: editor, terminal, browser, each where it belongs.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+Shift+D. Muscle memory needs things in the same place, so a layout file names what opens on which workspace, and one key lays the desk out. Deliberately not an autostart: you can decline it on the morning you want an empty machine.

Use

Run it (or press Super+Shift+D) and it opens what the layout names on the workspaces it names, without pulling your eyes along. The default layout is code; others are files you can write.

Examples

copal-deskthe 'code' layout
copal-desk --listthe layouts on this machine
copal-desk --show codewhat a layout does, without running it
copal-desk musica layout of your own

Options

NAME
lay out that layout (default: code)
--list
the layouts available
--show NAME
print a layout without running it

Notes

  • Layouts are NAME.layout files in /usr/local/share/copal/layouts (Copal's) and ~/.config/copal/layouts (yours, which wins over a system one of the same name).
  • The code layout: the editor and a terminal on 2, an agent on 3, the browser on 5, and an empty 1 to start from.
  • It works on both desktops: Hyprland places each window as it opens; i3 switches workspace first.

See also copal-camera, hyprctl

copal-desktop Choose which desktop takes the screen at the next login: Hyprland (Wayland) or X11.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: The choice is two settings that must agree: the word in /etc/copal/session, and whether X's setuid server is armed. Setting them in one command means they can never disagree -- and Wayland gets to disarm a root-privileged binary nothing is using.

Use

status (or no argument) shows what is set. wayland and x11 change it, and need doas; the change takes effect at the next login.

Examples

copal-desktopwhat is set, and whether X is armed
doas copal-desktop waylandHyprland next time
doas copal-desktop x11back to X11

Options

status
the session word, and the X server's state (the default)
wayland
Hyprland at the next login; X's setuid server disarmed
x11
startx at the next login; X's setuid server re-armed

Notes

  • wayland refuses, changing nothing, if Hyprland is not installed.
  • Disarming removes the setuid bit from /usr/libexec/Xorg.wrap. Xwayland, which runs X programs inside Hyprland, is a separate binary and is not affected.

See also copal-session, copal-startx

copal-fleet A fleet machine's own half of the fleet: what it announces, what it reports, and whether it has been enrolled.

Copal · Copal's own · stage 16 · Join the named fleet, and announce it

On Copal: A Copal fleet is a set of machines on one LAN that trust one certificate authority, run from a console. Each machine needs a small, readable program for its side -- announcing itself, reporting its health, taking part in choosing the warden -- and this is it.

Use

copal-fleet alone says what this machine thinks it is: its fleet, role, tags, scene, and whether it is enrolled. The other verbs are mostly for the console and the services; facts and state are good for a quick look.

Examples

copal-fleetthis machine's view of itself
copal-fleet factshealth, one fact per line
copal-fleet statethe same, on one line
copal-fleet browsewhich fleet machines this one can see
copal-fleet logs all 2the warden's collected logs, two days
rc-service copal-fleet statusthe service that keeps the beacon fresh

Options

status
fleet, node, role, score, tags, scene, authority, enrolment (the default)
state
one line of facts, for the console
facts
id, versions, uptime, memory, temperature, card use, certificate days...
id
the node's name
role
node or warden (or the pinned role)
score
this node's score in the warden election
elect
recompute the role
beacon
rewrite the mDNS announcement
watch
elect and rewrite the beacon every 4 minutes (the service)
browse
the fleet machines visible from here
install-cert
install a host certificate read from stdin (root)
bus-key
this node's bus identity, made if needed
bus-users
write the bus membership from stdin (warden, root)
bus-config
rewrite /etc/nats/nats.conf (warden, root)
bus-address
where the bus is
bus-state
what this node's part of the bus is doing
logs ID|all [DAYS]
the logs the warden has collected, even for a dead node
-h, --help
the usage

Notes

  • The fleet console is a different program on the operator's machine: copal fleet (make install-fleet on a Mac or Linux host). It reaches this one through copal-fleet-exec.
  • The warden is chosen by a score every node computes and publishes; the highest announcing node takes the role. role-pin in /etc/copal/fleet fixes a role by hand.
  • The settings are one file per field in /etc/copal/fleet. Stage 16 installs the program and the copal-fleet service.
  • The announcement says a machine is there, never that it is trusted: only its certificate decides that.

See also copal-fleet-exec, copal-fleet-agent, copal-remote, avahi-browse

copal-fleet-agent A fleet machine's standing connection to the fleet's message bus: presence, health and commands, all the time.

Copal · Copal's own · stage 16 · Join the named fleet, and announce it

On Copal: SSH answers when asked; the bus keeps the console's wall live without asking. The agent announces the machine, publishes its state as it changes, and runs commands that arrive on the bus -- through copal-fleet-exec, the same checked list SSH uses, so the bus can never do more than SSH can.

Use

You do not run it; OpenRC does, as the unprivileged copal-fleet account. Check on it with rc-service. --self-test runs its built-in checks without touching the network.

Examples

rc-service copal-fleet-agent statusis it running?
doas rc-service copal-fleet-agent restart
copal-fleet-agent --self-testits own checks

Options

--self-test
run the built-in checks and exit

Notes

  • It publishes hello every 10 seconds, the node's state on change (at most every 5 seconds), new lines of /var/log/copal-fleet.log, and an acknowledgement for every command it ran.
  • With no warden (and so no bus), it waits and tries again; that is normal during a handover, and SSH keeps working meanwhile.
  • On the warden it also collects every node's log lines, so the logs of a machine that has died can still be read (copal-fleet logs).
  • It publishes its own uptime, so the console can tell "the machine is up" from "the agent is alive".

See also copal-fleet, copal-fleet-exec, rc-service

copal-fleet-exec The only thing the fleet console's logins can run: a short, fixed list of verbs, each checked, each logged.

Copal · Copal's own · stage 16 · Join the named fleet, and announce it

On Copal: This is the fleet's security boundary. sshd sends every login by the copal-fleet account here, with no shell, no terminal and no forwarding, and what arrives is matched against a list of verbs rather than run as a command. A verb not on the list is refused and logged -- there is no pass-through.

Use

You do not run it; sshd does, as a forced command, with the console's request in SSH_ORIGINAL_COMMAND. The fleet agent hands bus commands to it the same way. Read it to know exactly what the console can do to a machine.

Examples

copal fleet run uptimefrom the console: one verb, every node
copal fleet run message Please stand back
doas tail /var/log/copal-fleet.logon a node: what was asked, and refused

Options

state, status, facts, score, id, uptime
reports; nothing changes
beacon
rewrite the mDNS announcement
power off|reboot
shut down or restart
snapshot restore
restore the node's snapshot (if it has copal-snapshot)
scene apply NAME
record the scene name; applying it is Ansible's job
bus key|users|state
the node's bus identity, membership (warden), state
logs ID|all [DAYS]
the warden's collected logs
log tail [N]
the last lines of this node's fleet log
remote start|stop|status
share the screen, bounded (see copal-remote)
message TEXT
put a sentence on the screen (see copal-notify)

Notes

  • A message is at most 200 characters of letters, digits, spaces and . , ! ? : and -: no quotes, brackets or slashes, so nothing in it can be read as markup or shell syntax.
  • A scene name is lowercase letters, digits and dashes.
  • Every request is logged with the caller's address to /var/log/copal-fleet.log; refusals are marked REFUSED.
  • Adding a verb means editing this file, and nothing else can add one: the bus agent parses no verbs of its own.

See also copal-fleet, copal-fleet-agent, copal-remote, copal-notify, sshd

copal-fonts Install Copal's font sets -- coding, console, IBM PC, web documents -- and set the text console's font.

Copal · Copal's own · stage 12 · The application catalogue

On Copal: Fonts in groups rather than one by one: the coding faces (with Nerd Font symbols for prompts), the console fonts, the classic IBM PC faces, and the metric-compatible set that makes a .docx look right. Stage 12 installs coding, console and ibmpc by default.

Use

With no arguments it shows what is installed, group by group. install adds a group; console sets the font of the text console (the one before the desktop, and after Ctrl-Alt-F2).

Examples

copal-fontswhat is installed, by group
copal-fonts list codingwhat a group contains
doas copal-fonts install webthe document fonts (about 120 MB)
doas copal-fonts install coding-extraIosevka and the large Nerd cuts (~1.9 GB)
doas copal-fonts consolethe console fonts available
doas copal-fonts console ter-v24nset one

Options

install GROUP...
coding, console, ibmpc, web, coding-extra, or all
list [GROUP]
a group's contents, and what is on disk
console [NAME]
list, or set, the text console's font
licences
where the fonts' licence files are

Notes

  • web is not installed by default: it matters only when a document from elsewhere looks wrong, and it is large. Install it when that happens.
  • Installing a group again only fetches what is missing.

See also starship, oh-my-posh

copal-gpu Say whether the desktop is drawn by the GPU or the CPU, layer by layer, and what to do about it.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: A slow desktop is usually software rendering, and the reason can be at any of four layers: the kernel's device, the host's VirGL offer, the compositor's renderer, or Mesa's. This checks each and reports the first fault only, because one fault makes every layer above it look wrong too.

Use

Run it inside the desktop. It lists what it found at each layer and ends with a verdict and, when there is a fault, the fix.

Examples

copal-gputhe report
copal-gpu >/dev/null; echo $?just the verdict, for a script

Options

Notes

  • The exit status is the verdict: 0 accelerated, 1 working but drawn on the CPU, 2 cannot tell yet (X has not run since boot).
  • Under Hyprland the answer is the Renderer: line in Hyprland's log: llvmpipe means software. Under X it reads the Xorg log for the driver and glamor, then asks glxinfo -B (package mesa-demos).
  • In a UTM virtual machine, 3D is the host's decision: "-virgl" in the kernel's messages means the display device offers none, and the fix is the VM's display setting (virtio-ramfb-gl), not anything inside.
  • On a Raspberry Pi, no DRM device and the framebuffer path are expected.

See also glxinfo, dmesg, copal-debug

copal-gui The other menu, Linux Mint's Cinnamon style: favourites, categories, icons and search, for the mouse.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+A. The mouse's menu beside copal-menu's keyboard one: hover a category to switch to it, hover a program to read about it, click to run. It sits over the screen as a layer, on the theme's own menu colours.

Use

Press Super+A (again to close). Categories on the left switch on hover, after a short pause; programs on the right describe themselves at the foot as you hover them; a click runs one. Type to search. Right-click a program to add or remove it from the favourites column.

Examples

copal-guiopen the menu, or close it if open
copal-gui --listevery entry: section|name|desktop id

Options

--list
print section|name|desktop-id for every entry, and exit

Notes

  • Scrolling by the edges: rest the pointer in the strip at the top or the bottom of the list and it scrolls at a steady pace; the rows in between stay still, so a click lands on what you aimed at. The wheel works as usual.
  • The favourites are kept in ~/.config/copal/gui-favourites, one per line: edit it, or right-click in the menu.
  • A click anywhere outside the menu closes it.

See also copal-menu, copal-apps

copal-guide Read Copal's plain-text guides, on the machine, with no network: tmux, nvim, languages, radio and more.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: The tutorials that come with Copal -- how the editor is set up, which languages this board has, software radio, the small web -- kept in /usr/local/share/copal/guides and opened by name. Super+/ (or Super+F1) opens the desktop's key guide.

Use

Without a name it lists the guides and asks which; with a name it opens that guide in the pager.

Examples

copal-guidethe list, then a choice
copal-guide nvimthe editor, from nothing to useful
copal-guide languageswhat this board has, and why
copal-guide radiosoftware-defined radio
copal-guide small-webGemini and Gopher

Options

NAME
open that guide (the file's name without .txt)

Notes

  • The guides are plain text files in /usr/local/share/copal/guides; less or grep reads them as well.
  • The stage that installs a feature writes its guide, so the list grows with what the machine has.

See also man, tldr

copal-halt End the session, and the machine, in one step: shut down, restart or log out, asking first.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+Shift+P and Session in the menu both run it. It closes the desktop properly first, so programs are asked to quit, then powers down -- from a terminal, a console or SSH alike, without typing the root password.

Use

With no argument it asks, then shuts down. reboot restarts, logout leaves the desktop and keeps the machine running. -y skips the question.

Examples

copal-haltshut down (asks first)
copal-halt rebootrestart
copal-halt logoutleave the desktop
copal-halt -y rebootrestart without asking

Options

(none)
shut down, after asking
reboot
restart
logout
end the desktop session only
-y, --yes
do not ask
-h, --help
the usage

Notes

  • It needs no password: a narrow doas rule, zz-copal-halt.conf, lets your account run only this. That rule is named to sort after the general wheel rule, because in doas the last match wins.
  • Inside i3 it closes the session first, so unsaved work gets its prompt before the power goes.

See also doas, rc-service

copal-install Install packages from the menu's Install branch, in a terminal that stays open to say how it went.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: What the menus run when you choose a program you do not have yet. It installs the packages, then -- where Copal Apps is present -- their man pages, optionals and group access, and refreshes the menu so the program is there the next time it opens.

Use

You rarely type it: the menus open a terminal running it. By hand, name the packages; a name ending @testing comes from Alpine's testing repository, and one ending @flathub from Flathub.

Examples

doas copal-install htopone package
doas copal-install maxima@testingfrom the testing repository
doas copal-install com.brave.Browser@flathuba Flatpak (~500 MB runtime first)

Options

PKG...
Alpine packages to install
NAME@testing
from edge/testing (the repository tag is added if needed)
NAME@flathub
a Flatpak from Flathub

Notes

  • The window waits for Enter at the end, so a failure's message can be read: the usual causes are no network, or a package this board's architecture does not have.
  • It needs root, and says so: run it with doas.
  • On a RAM-resident system it reminds you to lbu commit; an installed Copal machine does not need that.

See also copal-store, copal-menu, apk

copal-launcher Open the program launcher -- whichever this machine has: Copal's menu, wofi, or dmenu.

Copal · Copal's own · stage 17 · Hyprland and the Antiquity theme

On Copal: What the theme's launcher key runs. Linux Antiquity names its own launcher, which is not packaged for Alpine; this hands the key to copal-menu, falling back to wofi or dmenu.

Use

Press the launcher key (Super+Space) or run it; it opens the first launcher it finds.

Examples

copal-launcherthe menu, as the key opens it

Options

Notes

  • The order is copal-menu, then wofi --show drun, then dmenu_run; if none is installed it says so and exits.

See also copal-menu, copal-gui

copal-logflush Copy the logs kept in RAM down to the card, and back up at boot -- so they survive, with few writes.

Copal · Copal's own · stage 15 · What wears a card, logs, a read-only root

On Copal: An SD card wears with every small write. With /var/log in RAM, this chooses when to write: one complete copy each hour and at shutdown instead of a stream of appends. It is log2ram's design, in a few lines of shell.

Use

You do not run it by hand. It runs only if stage 15's "flush periodically" was chosen: hourly from cron, at shutdown, and at boot to restore.

Examples

doas copal-logflush savecopy the logs down now
ls /var/log.persistthe copy on the card

Options

save
/var/log (RAM) -> /var/log.persist, then sync (the default)
restore
/var/log.persist -> /var/log (at boot)

Notes

  • It does nothing unless /var/log is a tmpfs, so it cannot double the writes on a machine logging straight to the card.
  • A power cut loses up to an hour of logs; a clean shutdown loses none.
  • A log deleted from RAM is deleted from the copy too, by rsync's --delete where rsync is installed, and by a prune after cp -a where it is not.
  • The hooks are /etc/periodic/hourly/copal-logflush and /etc/local.d/copal-logflush.start and .stop.

See also copal-logs, rsync

copal-logs Find the logs that matter on a Copal machine, read them, and clear out the old ones.

Copal · Copal's own · written on every run of the installer

On Copal: The evidence for a desktop that will not start is in a file most people never find. This lists the desktop sessions, the install transcript and the system logs with their sizes, opens the one you want in a pager, and cleans up only what is safe to lose.

Use

With no argument it shows what exists and what it costs. x opens the newest desktop session log, errors picks out its error lines, install opens the install transcript.

Examples

copal-logswhat logs there are
copal-logs xthe last desktop session, in less
copal-logs x 2the one before it
copal-logs errors(EE), (WW) and error lines only
copal-logs installwhat the install stages did
copal-logs cleanremove old sessions and stale .bak files

Options

status
what exists, and its size (the default)
x [N], session [N]
a desktop session log; N counts back, 1 the newest
list
every desktop session log, newest first
errors
the error and warning lines from the newest session
install
the install transcript (copal.log on the boot partition)
clean
delete session logs beyond what copal-startx keeps, and stale .bak files
clean --all
the same, and rotate the install transcript to .1

Notes

  • The session logs are the X11 desktop's, written by copal-startx into ~/.local/state/copal: the latest two, or ten while copal-debug is on, which is also what clean keeps; a Hyprland session keeps its own log under $XDG_RUNTIME_DIR/hypr, which this does not read.
  • clean removes /etc/inittab.bak, /boot/copal-init.sh.bak and /etc/apk/world.bak, but only where the original is beside them. Run it with doas for those.
  • status says whether /var/log is in RAM (lost at reboot unless the flush is on) or on disk.

See also copal-startx, copal-debug, copal-logflush, less

copal-menu The keyboard menu: every program in one searchable list, and a second pane of categories, settings, Install and the session.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Super+Space (and Super+D, and the bar's button) open its left pane; Super+Z its right. Unlike a plain launcher it lists the terminal programs, the tools you would have to know the names of, and what you could install but have not.

Use

The left pane is every program, flat and sorted: type to filter, Enter to run. The right pane is the same programs by category, then Settings, Style, Install and the session (lock, log out, reboot, shut down). Left and Right cross between the panes; nothing is more than two levels deep.

Examples

copal-menuthe left pane (Super+Space)
copal-menu --systemthe right pane (Super+Z)
copal-menu --at-pointeropen where the mouse is
copal-menu --rebuildrebuild its list now
copal-menu --rebuild-allboth desktops' lists

Options

--system
open on the right pane
--at-pointer
open at the mouse pointer
--rebuild
rebuild the cached list for this desktop
--rebuild-all
rebuild it for both sessions (Hyprland and i3)

Notes

  • The list is cached in ~/.cache/copal so the menu opens in a fraction of a second; it rebuilds itself when programs change, and copal-install rebuilds it after every install. A program missing from the menu: copal-menu --rebuild.
  • It draws with wofi. Its scrolling is wofi's own: with the mouse, keep to the middle rows and use the wheel; the arrow keys always work.
  • The Install branch lists the catalogue's programs not yet installed; choosing one runs copal-install in a terminal.

See also copal-gui, copal-install, copal-apps

copal-morse Send text as Morse code, drill yourself on it, or print the table.

Copal · Copal's own · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts

On Copal: Alpine packages no Morse program at all, and Copal is a radio amateur's machine too. This one is written for timing: it builds the whole message as one sound file with sox, so the rhythm is exact even on a slow board where starting a program per beep would ruin it.

Use

Give it text and it plays and prints the code. -d is the drill: it sends five random letters, you type what you heard.

Examples

copal-morse cq cq de n0callsend it, at 13 words per minute
copal-morse -w 20 -f 700 sosfaster, and higher
copal-morse -q hello worldprint the dots and dashes only
copal-morse -pthe table
copal-morse -dthe drill (Ctrl-C to stop)
copal-morse -w 5 -da beginner's drill

Options

-w WPM
speed in words per minute (default 13)
-f HZ
tone in hertz (default 600)
-q
print the code, play nothing
-p
print the table and exit
-d
drill: it sends, you type
-h, --help
the usage

Notes

  • In the drill, Enter alone repeats the group and ? shows it; it keeps score of right and wrong.
  • Speed is by the standard word PARIS: at W words per minute a dot lasts 1200/W milliseconds. Letters, digits and common punctuation are sent; anything else is skipped.
  • It needs sox for sound (doas apk add sox); without it, it prints the code instead.

See also sox, play, direwolf

copal-notify Put one sentence on this machine's screen: as a notification, a Hyprland banner, or on the console.

Copal · Copal's own · stage 16 · Join the named fleet, and announce it

On Copal: The fleet's "message" verb lands here -- the museum's "please stand back". It uses whatever the machine has, in order of how much screen it takes: a Hyprland overlay, a notification, or the whole console on a machine with no desktop.

Use

Give it the text as one argument. Mostly it is called by the fleet, but it works as a quick message to the screen from a script or over SSH.

Examples

copal-notify "Back in five minutes"
copal-notify "Build finished"from the end of a long script

Options

TEXT
the sentence to show (required; quote it)

Notes

  • Inside Hyprland it uses hyprctl notify for 8 seconds; otherwise notify-send as a critical notification; with neither it writes the text to /run/copal/banner and to tty1.
  • It takes the text as a single argument and never re-splits or interprets it. The fleet limits a message to 200 characters of letters, digits and . , ! ? : - before it gets here.

See also copal-fleet-exec, notify-send, hyprctl

copal-readme-man Make a man page from a project's README.md, so man PROGRAM answers for programs built from source.

Copal · Copal's own · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts

On Copal: The programs in ~/code have READMEs and no man pages. This turns the parts of a README that are about using the program into a proper man page -- leaving out the badges, the build instructions and the licence -- so the manual works for them like everything else.

Use

copal-build runs it for every checkout it builds. Run it yourself to make or preview a page: give the README and the program names, and it writes roff to standard output.

Examples

copal-readme-man ~/code/staticstream/README.md sstr,ytq > sstr.1
copal-readme-man ~/code/ascitty/README.md ascitty > /tmp/a.1; man -l /tmp/a.1
copal-readme-man --markdown README.md ascittywhat goes in, as Markdown

Options

README NAME[,NAME...]
the page, as roff, on stdout
--markdown README NAME
the filtered Markdown instead, to review

Notes

  • It keeps the sections about using the program and drops the title, badges, images and HTML, and the sections a user of the installed program does not need: building, installing, downloading, licence, contributing, credits, status, roadmap, changelog and internals.
  • The NAME line lists every program named; the description is the first sentence of the README's first paragraph of prose. The date is the README's last commit, so the same README makes the same page.
  • A README's ## becomes a section, its ### a subsection. lowdown does the conversion (doas apk add lowdown).

See also copal-build, lowdown, man

copal-remote Share this machine's screen on the local network for a limited time: VNC on X11, RDP on Wayland.

Copal · Copal's own · stage 16 · Join the named fleet, and announce it

On Copal: For looking at a fleet machine's screen from the console. The machine decides how -- the server that matches its desktop -- and the limits are set on the machine, not by whoever asks: its LAN address only, a deadline, a switch to forbid it, and a log line at each end.

Use

start shares the screen until the deadline (30 minutes unless set otherwise), stop ends it now, status says what is running. Starting again while it runs restarts the clock.

Examples

copal-remote statusis the screen shared?
doas copal-remote startshare it
doas copal-remote stopstop now

Options

start
share the screen on the LAN address, until the deadline
stop
stop sharing
status
session, server, mode, minutes and address (the default)

Notes

  • On X11 it runs x11vnc on port 5900; on Wayland, hypr-rdp on 3389 with the node's certificate. Neither is part of a normal install.
  • VNC asks for the fleet's screen password: COPAL_FLEET_REMOTE_PASSWORD, set by make answers and kept on the node in /etc/copal/remote/passwd (root only). The console's seat answers with the same one. With no password set, stage 16 turns sharing off altogether, and start says why.
  • Classic VNC encrypts the login but not the screen, so keep it to a network you trust.
  • /etc/copal/remote/mode set to off forbids it -- the setting for a machine in a public place. /etc/copal/remote/minutes sets the deadline; 0 means none.
  • Wired interfaces are tried before wireless. Starts and stops go to /var/log/copal-fleet.log.

See also copal-fleet-exec, x11vnc, hyprctl

copal-session Start this machine's desktop -- Hyprland or X11, whichever /etc/copal/session names.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: One front door for the graphical session. The console login, the autologin and the documentation all say "run copal-session", and a single word in /etc/copal/session decides what that means, so they can never disagree.

Use

Log in on a console as your own user and run it. With the word wayland (and Hyprland installed) it starts Hyprland; otherwise it runs startx.

Examples

copal-sessionthe desktop
cat /etc/copal/sessionwhich one it will start
doas copal-desktop x11change it, safely

Options

Notes

  • It refuses to run as root: the desktop belongs to the admin user.
  • For Wayland it makes XDG_RUNTIME_DIR if nothing has (a private /tmp/xdg-runtime-UID, mode 700, refusing one someone else owns), then runs Hyprland through start-hyprland when present, inside dbus-run-session so the session's programs share one bus.
  • On the X path, if X's setuid helper has been disarmed it stops and names the fix, doas copal-desktop x11, instead of letting startx fail with "Only console users are allowed to run the X server".

See also copal-desktop, copal-startx, copal-autologin

copal-shot Super+Shift+S: drag a rectangle, and that part of the screen is saved as a picture.

Copal · Copal's own · stage 17 · Hyprland and the Antiquity theme

On Copal: The Hyprland desktop's screenshot key. The theme binds hyprshot, which Alpine does not package; copal-shot does the same with grim (grab) and slurp (select), which it does.

Use

Press Super+Shift+S, then drag over the area you want; release and it is saved to ~/Pictures as screenshot-DATE-TIME.png (to /tmp if there is no Pictures folder). Escape cancels.

Examples

copal-shotselect a region, save it
grim ~/Pictures/whole.pngthe whole screen, with grim directly
grim -g "$(slurp)" - | wl-copya region straight to the clipboard

Options

Notes

  • It saves without saying so: look in ~/Pictures.
  • For the whole screen, a window, or a copy on the clipboard, use grim directly, as in the examples.
  • On the i3 desktop (X11) screenshots are scrot; copal-shot is for Wayland.

See also grim, scrot, tesseract

copal-splash Draw the i3 desktop's key bindings onto the wallpaper, so the first screen teaches the keys.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: On the X11 desktop there is no welcome screen, and a tiling window manager with no visible menu is a blank wall to a newcomer. The keys, printed where the wallpaper would be, are the way in.

Use

i3 runs it at startup. Run it yourself after editing ~/.config/i3/keys.txt to see the change without logging out.

Examples

copal-splashredraw the desktop now
rm ~/.cache/copal-splash.png; copal-splashforce a fresh image

Options

Notes

  • It draws the bindings and group headings from keys.txt (the section from START SOMETHING to IF SOMETHING), at the screen's size from xrandr, with a line of the essential keys along the bottom.
  • The image is ~/.cache/copal-splash.png and is remade only when keys.txt is newer, so logging in costs nothing.
  • It needs ImageMagick to draw and feh to show; without them the desktop is a plain colour, set with xsetroot. It is for the i3 desktop only; Hyprland has its own wallpaper and Super+/ for the keys.

See also i3, copal-guide, feh

copal-ssh Read and change this machine's SSH login policy: passwords, root, and who may log in.

Copal · Copal's own · stage 6 · Install the SSH key from the card

On Copal: Copal writes its SSH policy as one marked block in sshd_config. This edits only that block, tests the result with sshd -t before reloading, and puts the old file back if sshd rejects it -- so a typo cannot lock you out of a machine you can only reach by SSH.

Use

copal-ssh shows the policy. The other forms need doas; each changes one setting and reloads sshd.

Examples

doas copal-sshwhat is in force
doas copal-ssh password offkeys only (refused if you have no key)
doas copal-ssh password onallow passwords again
doas copal-ssh root offno root login over SSH
doas copal-ssh users paul annaonly these accounts may log in

Options

status
password login, root login, allowed users, public keys
password on|off
allow or refuse password (and keyboard-interactive) login
root on|off
root by key only (prohibit-password), or refused
users NAME...
replace the AllowUsers list

Notes

  • password off refuses to act if the admin user has no ~/.ssh/authorized_keys, because it would lock the machine off the network. Copy a key in first (ssh-copy-id from your computer).
  • The block runs from # >>> copal ssh policy >>> to # <<< copal ssh policy <<<; delete it by hand and OpenSSH's own defaults apply. Every change leaves the previous file as sshd_config.copal.bak.
  • Every form, even status, needs root: sshd_config is not readable otherwise.

See also sshd, ssh-keygen, ssh-copy-id

copal-startx Start the X11 desktop as it should be started: not as root, with the right groups, and with a log kept.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: When X fails to start, the reason scrolls off the console it just took over. copal-startx is startx with that fixed: it refuses root, warns about missing groups, and writes every session's output to a file, printing the tail when the desktop exits with an error.

Use

Run it from a console login instead of startx; arguments are passed on to startx. On the Wayland desktop you want copal-session instead, which picks the right path for this machine.

Examples

copal-startxthe X11 desktop, logged
copal-logs xread the last session's log afterwards
COPAL_DEBUG=1 copal-startxone run with the debug collection

Options

(none)
start X, passing any arguments on to startx

Notes

  • It refuses to run as root, and says which account to log in as. Plain startx still works for the day you need a root desktop on purpose.
  • It warns if you are not in the video, input and tty groups, with the doas adduser line that fixes it.
  • The log is ~/.local/state/copal/xsession-DATE.log, with xsession-latest.log linked to the newest. Two are kept; with debug on (doas copal-debug on) ten are kept, and Xorg's own log is copied into each.
  • The log header records the tty, groups and graphics devices -- the facts that decide whether X may start and that are gone afterwards.

See also copal-session, copal-logs, copal-debug, startx

copal-store Copal Apps from the command line: find programs by what they do, install and remove them, with everything they need.

Copal · Copal's own · stage 18 · The Copal Store, and OpenShot compiled

On Copal: The engine behind Copal Apps and the menu's Install: every program Copal offers is a playbook, and copal-store runs it -- from an Alpine package, a Flatpak, a build from GitHub source, or a clone into ~/code -- then adds its man page, its optionals (plugins, codecs, format loaders) and the groups it needs.

Use

list and info to look; install and remove to change things (they ask for doas). With no arguments it opens the store window, or terminal menus where there is no desktop.

Examples

copal-store list Gamesa shelf: status, id, name
copal-store info gimpwhat it is, where from, how it installs
doas copal-store install gimp ffmpeg # install, with man pages, optionals, access
doas copal-store remove gimpand remove
copal-store optionalsthe optionals table
doas copal-store optionals --installedcatch up everything already installed
doas copal-store accessthe groups installed programs need
copal-store summarywhat each build did: result, size, "with", "absent"

Options

list [SECTION]
every program, or one shelf
info ID
one program: description, source, install method
install ID...
install (with man pages, optionals and access)
remove ID...
remove
recipes
the programs built from source
optionals [PKG...|--installed]
the plugins and helpers; install them
access [USER]
the groups programs need: plugdev, wireshark, dialout...
manpages PKG...
the man pages of these packages
summary
the build record
log ID
one build's full log

Notes

  • A build from source records what it compiled in ("with") and what it could not find ("absent") in the summary: the answer to which formats and codecs a build has.
  • Its logs are in /var/log/copal-store; the event stream Copal Apps reads is /var/log/copal/events.
  • Installed on medium and full installs (stage 18).

See also copal-apps, copal-install, apk

copal-terminal-theme Write a colour theme into the terminal emulators' configs: foot, kitty, alacritty and the rest.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: The terminal part of the desktop's look, on its own: copal-theme calls it, and it can be run by hand for a different terminal palette or opacity.

Use

Name a theme and it writes it into every terminal configuration in your home; with no name it follows the desktop's current theme. Open terminals pick it up when they next start.

Examples

copal-terminal-themefollow the desktop's theme
copal-terminal-theme --listthe palettes there are
copal-terminal-theme sandCopal's own light palette
copal-terminal-theme night --alpha 1 # Tokyo Night, fully opaque
copal-terminal-theme --show erisprint a palette, change nothing

Options

THEME
helios, eris, priapus, eros, hades (Linux Antiquity), night, sand
--list
the theme names --show THEME print the palette and stop
--alpha A
window opacity, 0.5 to 1 (default 0.9)

Notes

  • $COPAL_TERMINAL_THEME overrides what "follow the desktop" means.
  • Only terminals already configured in your home are rewritten; a terminal installed later gets the theme the next time this runs.

See also copal-theme, foot

copal-theme One switch for the whole desktop's look: bar, borders, wallpaper, GTK, terminal, menus and editor together.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: Copal's desktop is themed in a dozen places -- Hyprland, the bar, wofi, GTK, the terminal, Neovim, mc. copal-theme changes all of them at once, so nothing is left in the old colours.

Use

With no argument it lists the themes, the current one starred. A name switches to it; --toggle swaps light and dark; --pick offers a menu (Super+Shift+T, or Style in the menu).

Examples

copal-themethe themes, * the current
copal-theme tokyo-nightswitch everything to it
copal-theme --togglelight <-> dark (Super+Shift+N)
copal-theme --pickchoose from a menu
copal-theme --show antiquitya theme's colour tokens

Options

NAME
switch to NAME
--toggle
the current theme's light or dark partner
--pick
choose from a menu (Super+Shift+T)
--show [NAME]
print a theme's tokens
-q, --quiet
say nothing but errors

Notes

  • The colours are written to ~/.config/copal/current/colors.css, which the bar, wofi and the Super+A menu read: a running Neovim follows the change without restarting.
  • Themes shipped: Antiquity (helios, light) and Tokyo Night (dark).

See also copal-terminal-theme, copal-wallpaper, copal-gui

copal-times How long each package took to install, which ones pulled in the most, and what could be reordered.

Copal · Copal's own · written on every run of the installer

On Copal: A Copal install is hours on a small board, and the time goes somewhere measurable. The installer records every package's time and dependencies; this reads that record to show what was slow and, more usefully, which package's position in the order decided what everything after it cost.

Use

With no argument: the fifteen slowest packages and the total. groups shows the time by stage section; order and shared are the views for deciding what to install first.

Examples

copal-timesthe slowest fifteen
copal-times groupstime by section
copal-times orderwhat pulled the most in, and where it sat
copal-times sharedprerequisites many packages needed
copal-times deps gccwhat gcc brought with it
copal-times totalone line: packages, failures, time
copal-times csv > times.csvfor a spreadsheet

Options

(none), top
the slowest fifteen, and the summary
all
every package, slowest first
groups
time and count by section
order
the packages that pulled in the most, with their position
shared
dependencies wanted by more than one package
deps PKG
what one package brought with it
total
packages, already present, failed, and the install time
csv
the whole record as CSV
--motd
rewrite the login message's summary (needs doas)
--reset
clear the record (needs doas)
-h, --help
the usage

Notes

  • PULLED is how many other packages came with one. A long time with "-" is a package that is genuinely expensive; a long time with "+13" is one that happened to be asked for first and paid for the dependencies.
  • The record is /var/lib/copal/install-times.tsv, with dependency sets in install-deps.tsv; older six-column records still read.

See also apk, copal-install

copal-wallpaper Choose and paint the desktop's wallpaper, from the theme's collection or your own pictures.

Copal · Copal's own · stage 17 · Hyprland and the Antiquity theme

On Copal: Hyprland's own wallpaper tool, hyprpaper, is not packaged for Alpine; copal-wallpaper paints with swaybg, remembers the choice, and is what the session starts.

Use

--pick shows thumbnails to choose from; set FILE uses any picture. Without arguments it paints the chosen one and keeps running -- the session starts it that way.

Examples

copal-wallpaper --pickchoose, with thumbnails
copal-wallpaper set ~/Pictures/lake.jpgany picture of yours
copal-wallpaper --listwhat is available, and from where
copal-wallpaper --fetchdownload diinki's published collection

Options

--pick
choose one, with thumbnails
set FILE
use FILE from now on
--list
the wallpapers, and where each came from
--fetch
download the theme author's full collection

Notes

  • The bundled wallpapers are in ~/.config/hypr/wallpapers_bundled; --fetch adds the rest of the collection.
  • The choice is remembered across logins; set is all it takes.

See also copal-theme

copal-widgets The clock, date and weather on the wallpaper: show them, hide them, and see where they come from.

Copal · Copal's own · stage 4 · X.Org, i3, a terminal and a browser

On Copal: The desktop layer's widgets. The theme's own widget shell, quickshell, is not packaged for Alpine, so waybar draws them; this command turns them on and off without touching the bar, and seeds the theme's own widget file for the day quickshell arrives.

Use

--off hides them, --on brings them back, both at once; --status says which are running and from where.

Examples

copal-widgets --statuswhat is running
copal-widgets --offhide the clock and weather now
copal-widgets --onshow them again
copal-guide widgetsthe longer version

Options

--on
show the widgets
--off
hide them
--status
which are running, and from where
--seed
place the theme's widgets in its quickshell file (run at login)

Notes

  • What is drawn and where is ~/.config/waybar/desktop.json; the type and colours, desktop.css beside it. Nothing regenerates those files once they exist, so edits stay.

See also copal-bar, copal-theme

Appearance

oh-my-posh A shell prompt engine with a hundred ready-made themes.

Appearance · command-line tool · built from source by Copal Apps · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf

On Copal: The store's other prompt: built by Copal Apps from source, with its whole theme collection, for anyone who wants to pick a look rather than design one.

Usage:
  oh-my-posh [flags]
  oh-my-posh [command]

Use

Initialise it in your shell's start-up file with a theme; the next shell has that prompt. The themes are JSON files: try one, keep the one you like, or copy it and change it.

Examples

ls /usr/local/share/oh-my-posh/themesthe themes
echo 'eval "$(oh-my-posh init bash --config /usr/local/share/oh-my-posh/themes/jandedobbeleer.omp.json)"' >> ~/.bashrc
oh-my-posh print primary --config THEME.omp.jsonpreview a theme's prompt
oh-my-posh debugtiming of each segment, to find a slow one

Options

init SHELL
print the line that turns it on; --config THEME
print primary
print the prompt, to preview
config
read or export the configuration
debug
show what each segment costs
font
install a Nerd Font for the icons
version
the version

Notes

  • Most themes need a Nerd Font; without one the icons show as boxes. copal-fonts install coding brings them.
  • A theme that runs git in every prompt can feel slow on a Pi in a big repository; oh-my-posh debug shows which segment it is.

See also starship

starship A fast, configurable shell prompt: the folder, git state, language versions, all at a glance.

Appearance · command-line tool · starship 1.24.2 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs dbus-libs

On Copal: The store's prompt for any shell: one line added to the shell's start-up file, and the prompt shows the branch, what changed, how long the last command took and whether it failed.

Usage: starship <COMMAND>
Commands:
  bug-report    Create a pre-populated GitHub issue with information about your configuration

Use

Add its init line to your shell's start-up file; the next shell has the prompt. Change it in ~/.config/starship.toml, or start from one of its presets.

Examples

echo 'eval "$(starship init bash)"' >> ~/.bashrcturn it on for bash
starship preset --listthe ready-made looks
starship preset gruvbox-rainbow -o ~/.config/starship.tomluse one
starship explainwhat each part of the prompt is
starship toggle git_statusswitch a part off, and on again

Options

init SHELL
print the line that turns it on (bash, zsh, fish...)
preset NAME
print a preset; -o FILE to write it
explain
describe the prompt you are looking at
config
edit the configuration
print-config
the configuration in force
toggle MODULE
turn one part on or off

Notes

  • Many presets use Nerd Font symbols: without such a font they show as boxes. copal-fonts install coding brings them.
  • For the Linux console, a plain preset (plain-text-symbols) avoids symbols the console font lacks.

See also oh-my-posh, git

Audio

fluidsynth A software synthesiser: play MIDI files, or MIDI keyboards, through a SoundFont.

Audio · command-line tool · fluidsynth 2.5.4 · stage 12 · The application catalogue · man fluidsynth(1) · home

needs fluidsynth-libs, glib, pipewire-libs

On Copal: The catalogue's MIDI synthesiser, installed with a General MIDI SoundFont (TimGM6mb) so a .mid file makes sound straight away, and a USB keyboard becomes an instrument.

fluidsynth [options] [ SoundFonts ] [ midifiles ]

Use

Give it a SoundFont -- the instrument samples -- and MIDI files to play, or leave it running for a keyboard or a sequencer to play through. It starts an interactive prompt unless told not to.

Examples

fluidsynth -i -a alsa /usr/share/soundfonts/default.sf2 song.midplay a file
fluidsynth -F song.wav /usr/share/soundfonts/default.sf2 song.midrender to WAV
fluidsynth -a alsa /usr/share/soundfonts/default.sf2a synth for a keyboard
aconnect -lMIDI ports; connect keyboard to synth with aconnect A B

Options

-a DRIVER
the audio driver: alsa or pulseaudio (both reach PipeWire)
-i, --no-shell
no prompt: play and exit
-F FILE
render to FILE instead of playing
-g GAIN
the volume, 0 to 10 (default 0.2)
-r RATE
the sample rate
-q, --quiet
no banner -n, --no-midi-in no MIDI input

Notes

  • Without -i it waits at its own > prompt after the file ends; quit leaves.
  • The default gain is quiet on purpose; -g 1 for a louder start.
  • A pages-long run of "ALSA lib ... Unknown PCM" at start is ALSA probing devices that do not exist; it is noise, not failure.
  • Better SoundFonts are a download away: any .sf2 file works the same.

See also openmpt123, xmp, alsamixer

openmpt123 Play tracker music -- MOD, XM, S3M, IT and dozens more -- in the terminal, accurately.

Audio · command-line tool · openmpt123 0.8.9 · stage 12 · The application catalogue · man openmpt123(1) · home

needs libflac, libopenmpt, portaudio, libpulse, libsndfile

On Copal: The catalogue's module player, built on OpenMPT's library: the most faithful playback of the music of the Amiga and PC demoscene.

openmpt123 [options] [--] file1 [file2] ...

Use

Give it module files; it plays them in order and shows the pattern position. It can also render a module to a WAV or FLAC file.

Examples

openmpt123 song.xmplay
openmpt123 *.moda folder, in order
openmpt123 --shuffle ~/Music/mods/*in any order
openmpt123 --render song.itwrite song.it.wav, and play nothing
openmpt123 --info song.s3mtitle, format, length, channels
Space (while playing) pause
h l seek 10 s back / forward (j k: 1 s)
n m previous / next file
3 4 quieter / louder; q quit

Options

--render
render each file to a WAV beside it
--info
print the module's details only
--shuffle
shuffle the files
--repeat N
repeat each song N times (-1 forever)
--gain DB
the volume, in dB
-q, --quiet
no display
--driver NAME
the audio output
--help-keyboard
every key it answers while playing

Notes

  • Modules are tiny: a three-minute XM is often under 100 kB. The Mod Archive (modarchive.org) holds over a hundred thousand.
  • If there is no sound, --driver help lists the outputs this build has.

See also xmp, fluidsynth

pactl PulseAudio's control command, answered here by PipeWire.

Audio · pulseaudio-utils 17.0 · stage 10 · Wireless, audio, capture and disks · man pactl(1) · home

needs libintl, libpulse, libsndfile, libxcb

On Copal: Copal runs pipewire-pulse, so programs written for PulseAudio work unchanged -- and pactl, which most answers online use, works too. For everyday volume and output, wpctl is the native tool.

pactl [options] COMMAND [ARGS ...]

pactl --help

pactl --version

Use

List the outputs (sinks) and inputs (sources) by name, change their volume, and move a playing stream from one device to another. The special names @DEFAULT_SINK@ and @DEFAULT_SOURCE@ save looking them up.

Examples

pactl infothe server: PipeWire, via pulse
pactl list short sinksoutputs, one line each
pactl set-sink-volume @DEFAULT_SINK@ +5%louder
pactl set-sink-mute @DEFAULT_SINK@ togglemute
pactl set-default-sink alsa_output.platform-hdmia named output as default
pactl list short sink-inputswhat is playing right now
pactl move-sink-input 42 @DEFAULT_SINK@move stream 42 to the default output
pactl subscribewatch events as they happen

Options

info
the server and its defaults
list [short] TYPE
sinks, sources, sink-inputs, cards, modules
set-sink-volume NAME VOL
50%, +5%, -5%
set-sink-mute NAME 1|0|toggle
mute
set-default-sink NAME
the default output
move-sink-input N SINK
move a playing stream
-f, --format=json
JSON output

Notes

  • pactl info saying "Server Name: PulseAudio (on PipeWire ...)" is right: it is PipeWire's pulse layer. There is no PulseAudio daemon, and pulseaudio -k answers are not for this system.
  • "Connection refused": no PipeWire in this session -- over SSH, say. See wpctl.

See also wpctl

wpctl Control PipeWire's audio: volume, mute, and which device plays.

Audio · wireplumber 0.5.15 · stage 10 · Wireless, audio, capture and disks · home

needs glib, libintl, lua5.4-libs, pipewire-libs, wireplumber-libs

On Copal: Copal's sound is PipeWire with WirePlumber, started with each session by copal-audio-start. The desktop's volume keys are wpctl commands; so is changing the output from HDMI to headphones.

Use

wpctl status lists the devices -- sinks are outputs, sources are inputs -- each with an ID number, and marks the default with *. Every other command takes an ID, or @DEFAULT_AUDIO_SINK@ for the current output.

Examples

wpctl statusdevices, IDs, the default
wpctl get-volume @DEFAULT_AUDIO_SINK@the output's volume
wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+up 5% (5%- for down)
wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+ # up, but never past 100%
wpctl set-mute @DEFAULT_AUDIO_SINK@ togglemute, and back
wpctl set-default 48make device 48 the output
wpctl inspect 48everything about it

Options

status
the whole graph: devices, sinks, sources, streams
get-volume ID
the volume, 1.00 being 100%
set-volume ID VOL[%][+-]
set, or step up or down
set-mute ID 1|0|toggle
mute, unmute, toggle
set-default ID
the default output or input
inspect ID
all of a node's properties
set-volume -l N ID VOL
go no higher than N (1.0 = 100%)

Notes

  • "Could not connect to PipeWire": no PipeWire is running for this user in this session -- typical over SSH or on a console. Run it from the desktop's terminal, or start it with copal-audio-start.
  • IDs change between sessions. In a script, use @DEFAULT_AUDIO_SINK@ and @DEFAULT_AUDIO_SOURCE@, not numbers.
  • The RTKit warnings it prints first ("RTKit error ... ServiceUnknown") are harmless: there is no RTKit on Copal, and audio runs without it.

See also pactl, bluetoothctl

xmp The Extended Module Player: tracker music in the terminal, with a channel-by-channel view.

Audio · command-line tool · xmp 4.2.0 · stage 12 · The application catalogue · man xmp(1) · home

needs alsa-lib, libpulse, libxmp

On Copal: The catalogue's other module player: small, and it can solo and mute channels as it plays -- the way to hear how a tracker song is built.

xmp [-a, --amplify factor] [-A, --amiga] [-b, --bits bits] [-C, --show-comments] [-c,
--stdout] [-D device-specific parameters] [-d, --driver driver] [-e, --player-mode mode] [-F,
--nofilter] [-f, --frequency rate] [--fix-sample-loop] [-h, --help] [-I, --instrument-path]
[-i, --interpolation type] [--load-only] [-L, --list-formats] [-l, --loop] [--loop-all] [-M,
--mute channel-list] [-m, --mono] [--mixer_voices num] [-N, --null] [--nocmd] [-o,
--output-file filename] [-P, --pan num] [-p, --default-pan num] [--probe-only] [-q, --quiet]
[-R, --random] [-S, --solo channel-list] [-s, --start pos] [-t, --time time] [-u, --unsigned]
[--vblank] [-V, --version] [-v, --verbose] [-Z, --all-sequences] [-z, --sequence num] modules

Use

Play module files; the display shows the patterns and channels moving. Number keys mute channels while it plays, so the parts can be heard one at a time.

Examples

xmp song.modplay
xmp -l song.xmloop it
xmp -o song.wav song.xmrender to a WAV instead of playing
xmp -S 0,1 song.modonly channels 0 and 1
xmp -Levery format it reads
1..0 (while playing) mute or unmute channels 1 to 10
Space pause; f / b next / previous pattern
q quit

Options

-l, --loop
loop the song
-o, --output-file F
write to F instead of playing
-S, --solo LIST
play only these channels
-a, --amplify N
amplification, 0 to 3
-d, --driver NAME
the output driver
-L, --list-formats
the formats it reads

Notes

  • It comes from Alpine's testing repository (xmp@testing).
  • For the most faithful playback of IT and newer formats, openmpt123 is the reference; xmp is lighter and shows more.

See also openmpt123, fluidsynth

Browsers

browsh The modern web in a terminal: a real Firefox renders the page, browsh draws it in text.

Browsers · terminal program · built from source by Copal Apps · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf

On Copal: The store's browser for pages the text browsers cannot show -- JavaScript, video thumbnails, modern layouts -- over SSH or on a console, with Firefox ESR doing the rendering headless.

Use

Start it with an address; Firefox runs in the background and browsh draws the page with coloured characters. Ctrl-l goes to a new address; the mouse clicks links where the terminal passes clicks.

Examples

browshits start page
browsh --startup-url https://example.comopen a page
browsh --monochromefor terminals without colour
browsh --http-server-modeserve pages as plain HTML to other machines
Ctrl-l (in browsh) type an address
Backspace back
Ctrl-t / Ctrl-w a new tab / close it
Ctrl-q quit

Options

--startup-url URL
the page to open
--monochrome
no colour
--http-server-mode
run as an HTTP service instead of a terminal UI
--time-limit SECS
quit after SECS seconds
--firefox.path PATH
which Firefox (Copal's launcher passes firefox-esr)

Notes

  • It is Firefox underneath, so it costs Firefox's memory: a few hundred MB, and a slow start on a small Pi.
  • Not on ARMv6 (the first Zero): its row is gated off there.

See also links, w3m, firefox-esr

Code

ascitty A raytraced city of typeable characters, in real time in a terminal -- with a taxi game inside.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man ascitty(1), from its README

On Copal: One of the checkouts in ~/code, built by copal-build: a showpiece for a colour terminal, and a test of one. The same city runs on a Commodore Plus/4.

Use

Start it and a cab drives itself round the city, taking fares. Touch a key and you are driving: wasd is the vehicle, the arrows are the view, and \ hands it back to the autopilot. The frame is the size of the window, so a bigger terminal is a bigger city.

Examples

ascittythe city, the cab driving itself
ascitty --playat the wheel from the start
ascitty --walkon foot instead
ascitty --copterabove the city
ascitty --mode ascii --color none7-bit, no colour: the mode the name is about
ascitty --shot 30 > city.txtrender 30 frames, keep the last as text
ascitty --bench200 frames as fast as it can, and a report
w a s d (in the city) throttle, steer left, brake/reverse, steer right
q e hard left / hard right
space z brake / handbrake
t get out and walk
\ back to the autopilot; Esc quit

Options

--play
drive from the start, no autopilot
--walk
on foot
--copter
in the air
--mode M
ascii or unicode (default unicode)
--color D
true, 16 or none (default: from $COLORTERM)
--size WxH
a fixed frame instead of the window's size
--fps N
frame rate cap (default 30)
--seed N
another city
--sky N
start at phase N of 12: 0 night, 3 sunrise, 5 noon, 8 sunset
--shot [N]
render N frames, print the last, exit
--bench
measure the renderer

Notes

  • The terminal is the bottleneck, not the renderer: a big frame takes the renderer a millisecond and the terminal twenty. Bands of the picture a frame behind mean the terminal is falling behind -- a smaller window or --fps 15 fixes it.
  • Hold the keys: the throttle winds on while it is down, as the steering does, so a tap does very little.
  • --color follows $COLORTERM; set --color 16 if the colours look wrong over SSH.

See also copal-build, copal-terminal-theme

birdshot Bird and sky capture for the Raspberry Pi HQ Camera, from the command line.

Code · command-line tool · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man birdshot(1), from its README

On Copal: Copal's camera. copal-build builds the C++ pipeline from the birdshot checkout; birdshot-gui is its window (Super+Shift+B), and this is the same pipeline for a script or an SSH session.

Use

Capture with metered auto-exposure and quality gates that drop blurred or badly exposed frames, fast bursts, timelapses, or a watch on the sky that fires when a bird crosses it. Then stamp the EXIF and assemble a session's frames into a video.

Examples

birdshot infothe camera, its modes, storage, calibration
birdshot doctorwhat is missing or wrong, and the fix
birdshot capture -n 200200 frames through the full pipeline
birdshot rapid -n 500the fastest path: flat, timed names
birdshot timelapse -i 5 -n 720one frame every 5 s, for an hour
birdshot birdflight -n 20watch the sky; fire on a bird, 20 takes
birdshot sessionswhat has been captured, by session
birdshot assemble SESSION --fps 60a session's frames into an MP4 (ffmpeg)
birdshot sunthe sun now, and today's events

Options

capture [-n N] [-v]
the full pipeline, with quality gates
rapid [-n N]
fastest single photos
timelapse [-i SEC] [-n N]
one frame every SEC seconds
birdflight [-n TAKES]
trigger on a bird
gui [--port N]
the live pipeline in a browser
exif DIR
stamp EXIF into a session, losslessly
assemble DIR [--fps N]
frames to a movie; --out FILE
sun / plan / site
where the sun is, a plan for the days ahead, your site
info / sessions / doctor / selftest
the housekeeping
--config PATH
another settings file

Notes

  • It is for an IMX477 -- the Pi HQ Camera. Other cameras are not what its exposure ladder and gates are tuned for; birdshot doctor says what it found.
  • Settings live in ~/.config/birdshot/settings.json; every command reads it, and --config points at another.
  • The first run of the window offers a calibration wizard, about a minute. Its numbers are what the quality gates judge by: run it.

See also copal-camera, copal-build

copal-tm Copal's task manager: an instrument panel and a process browser in one terminal window.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man copal-tm(1), from its README

On Copal: The task manager on Copal's full install, built by copal-build from its checkout: what the machine is doing, which process is doing it, and a considered way to stop one.

Use

The top half is the instrument panel -- CPU, memory, swap, temperature, network, pressure; the bottom half is the process tree. Select a process and press k to send it one signal, or x for the Halt plan: the gentle signals first, the hard one last, with the reasons shown.

Examples

copal-tmthe panel and the browser, split
copal-tm --view dashboardthe instrument panel only
copal-tm --view browserthe process list only
copal-tm --refresh 0.5tick twice a second
copal-tm --dump-config > ~/.config/copal/taskman.confa config to edit
F1 F2 F3 (in the window) dashboard / split / browser
Enter i the Inspector: attributes, contents, network, tools, access
k x send one signal / the Halt plan
/ s t filter / sort / tree
T the Transcript: every signal sent, and why
? q keys / quit

Options

--view MODE
split, dashboard or browser
--refresh SECONDS
the tick, 0.25 to 10 (default 1.0)
--charset SET
auto, full, blocks or ascii
--color MODE
auto, truecolor or 16 --browser.sort KEY cpu, mem, pid, time, name or user
--theme NAME
copal or mono
--simulate
run against a simulated machine
--dump-config
print the effective configuration

Notes

  • k shows each signal's disposition -- whether the process catches, ignores or dies of it -- before you send it; the Halt plan uses those.
  • The configuration is ~/.config/copal/taskman.conf, key = value, and every key is also a flag of the same name.
  • It degrades legibly: on a 16-colour console or an ASCII-only terminal it still draws, with --charset ascii.

See also htop, btop, copal-halt

orrery The console for a fleet of Copal machines: the wall, the seat, and the museum interface.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man orrery(1), from its README

On Copal: Stage 16's fleet -- a room of Copal machines -- is watched and run from it: every machine at once on the wall, one of them full screen in the seat. Built by copal-build from the orrery checkout.

Use

Three faces. The wall is a web page of every machine in the fleet, served on a port. The seat is one machine, observed and controlled over VNC, full screen in this terminal. The native window (--gui) is the museum interface. Without --operator it only observes; with it, the verbs that act on machines are enabled.

Examples

orrery --demothe wall, from a fixture: no fleet needed
orrery --gui --demo --operator xthe museum interface, from the fixture
orrerythe wall, on 127.0.0.1:8080
orrery --listen 0.0.0.0:8080the wall, for the room's gallery screen
orrery --gui --operator TOKENthe window, with the write verbs on
orrery --seat museum-01one node, full screen, over VNC

Options

--listen HOST:PORT
where the wall is served (default 127.0.0.1:8080)
--operator TOKEN
enable the verbs that change machines
--fleet NAME
which fleet (passed to copal fleet)
--demo
serve from a fixture instead of a fleet
--gui
the native window instead of a web page
--seat NODE
one node over VNC; --fps N, --vnc-port N
--frame PATH
render one frame to a PPM and exit (works headless)
--dark
the night palette
--quiet
do not log requests

Notes

  • The default listens on loopback only. The gallery screen needs --listen 0.0.0.0:8080, which puts the wall on the LAN: a LAN you trust.
  • Read-mostly by default is deliberate. --operator is what turns a display into a control panel.
  • The seat asks a node for 6 frames a second, because frame rate is the expensive axis; --fps raises it.

See also copal-fleet, ssh

radbeeper A GQ GMC Geiger counter on the desk: find it, watch it, log it, and pull its history.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man radbeeper(1), from its README

On Copal: Stage 10 sets up the Geiger counter; radbeeper, built by copal-build from its checkout, is the command the counter's instrument panel (radbeeper-gui) is built on.

Use

Plug the counter in by USB, radbeeper probe to find it, radbeeper watch to see its rate over five time spans at once while it logs. It also downloads what the counter recorded on its own, and turns the timing of decays into random numbers.

Examples

radbeeper probefind the counter, say what it is
radbeeper watchthe monitor, logging while it is open
radbeeper cpmits counts per minute, once
radbeeper clockits clock against this machine's
radbeeper clock --setcorrect it
radbeeper log pulldownload the history in its flash
radbeeper backfillfill the log's gaps from that history
radbeeper random256 bits of hex, from decay timing

Options

probe
find and identify the counter
watch
the live monitor
cpm
one reading
clock [--set]
compare, or set, the counter's clock
log info|pull
what history it holds / download it
backfill
fill gaps in the log from the counter's memory
random
random bits from decay timing; --check F to verify a log
-d, --device PATH
the serial port; repeat for a second counter
-b, --baud RATE
the baud (default: 115200, then 57600)
--duration SECONDS
stop after this long
--logs DIR
where logs are written and read

Notes

  • Nothing found? probe says what went wrong, because each cause has its own fix. "Permission denied" means the account is not in dialout, which owns the serial port: doas adduser $USER dialout, then log in again.
  • Set the clock first (clock --set): the history in the counter's flash carries the counter's own timestamps.
  • The default tube factor is 151.5 CPM per µSv/h, the GMC-320's; --cpm-per-usvh for another tube.
  • doas dmesg | tail after plugging it in shows the serial port it got.

See also copal-build, dmesg

sstr Record a stream into a .sstr file, with its order, pace and damage tolerance kept, and play it back.

Code · command-line tool · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man sstr(1), from its README

On Copal: The archive format ytq keeps its downloads in. Built by copal-build from the staticstream checkout; sstr export turns captures back into ordinary files whenever you want them.

Use

sstr record writes a stream -- a file, or stdin -- into a capture; sstr play lets it out again: to a file, to stdout at the pace it was recorded, or to VLC or mpv over the network. Every record carries Reed-Solomon parity (about 21 % more bytes), so a damaged capture is repaired as it is read. Nothing is encrypted and nothing is decoded.

Examples

sstr record talk.sstr --input talk.mp4capture a file
sstr play talk.sstr -o talk.mp4and back out as the file
sstr play talk.sstr --paced | mpv -at the pace it was recorded
sstr play talk.sstr --serve :8080serve it to a player on the LAN
sstr verify talk.sstrcheck it; say what was repaired
sstr export ~/Videos/archiveevery capture in a folder, back to files
sstr export . -nwhat that would write, first
sstr config listthe settings in force

Options

record OUT
capture stdin, or --input FILE, into OUT
play IN
write the stream back; -o FILE, --paced, --speed N
play IN --serve A
serve it over HTTP at HOST:PORT
verify IN
check every record and signature
export PATH...
captures or folders back to files; -r, -n, --into DIR
config
list, get, set or unset a setting
--key KEY
sign the checkpoints with this SSH key
--allowed-signers F
trust signatures by these keys, when reading
-
as IN or OUT: stdin or stdout

Notes

  • Checkpoints are signed with your SSH key, which proves who recorded it; they are not encrypted. Anyone with the file can play it.
  • export with --remove deletes each capture once its file is out and checked; without it, both stay.
  • A capture can be played or served while it is still being recorded: --follow keeps going as it grows, so mpv or VLC can watch it live.

See also ytq, sstr-workspace

sstr-workspace One terminal window over the download queue and the archive: browse, play, verify, export.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man sstr-workspace(1), from its README

On Copal: Super+Shift+A. The Workspace over ytq's queue and the folders of Static Stream captures it fills, from the staticstream checkout -- every action one key, and every action a command line you can read.

Use

A column browser. Move through folders and the queue, look at a capture in the Inspector, and send it a Service -- play, verify, export -- with one key. Each Service is written into the Transcript as a command line before it runs, so you see exactly what was done and can type it again.

Examples

sstr-workspacethe download queue, live
sstr-workspace ~/Videos/archivebrowse a folder of captures
up/down j/k (in the window) move
Enter l open a folder; h back out
Space put the selection on the Shelf, or take it off
p P s v play / play paced / serve / verify
x t a export / text / armor
r f retry / forget a queue entry
Q ytq's queue as one more column; q leave

Options

DIR
browse DIR instead of the queue
Space
the Shelf: a Service then goes to everything on it
d
one line per queue entry, or two

Notes

  • The archive folder is ARCHIVE_DIR in ~/.config/copal/media.conf, then ~/.config/ytq/config -- where ytq reads it. The player (mpv) and the serve address come from the same files.
  • A Service that prints takes the terminal until a key is pressed; the window comes back after it.

See also ytq, sstr

ytq A download queue that watches the clipboard, and keeps what it fetches as Static Stream.

Code · terminal program · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man ytq(1), from its README

On Copal: Copy a video's link, press Super+Shift+Y, and it is queued. Built by copal-build from the staticstream checkout in ~/code; the Rust ytq replaced the Python one Copal used to write.

Use

Queue links, then download them one at a time with yt-dlp, best video and audio merged. The queue is one file shared by every ytq at once, so ytq add works while ytq run is downloading. Each download also gets a .txt beside it: the full title, author, URL, dates, the description and the captions, so it can be cited later.

Examples

ytqthe queue window; queues the clipboard's URL
ytq clipqueue what is on the clipboard (Super+Shift+Y)
ytq add https://youtu.be/dQw4w9WgXcQ # queue a URL from the shell
ytq rundownload everything queued, here
ytq statuswhat is downloading, and what is left
ytq listevery entry: queued, done, waiting, failed
ytq transcript URLonly the captions, as text
ytq cookiesretry what waited for a Brave sign-in
touch ~/.config/ytq/autostart downloading by itself from now on

Options

clip
queue the clipboard's URL, or every YouTube link in it
add URL...
queue URLs
run
download the queue in this terminal
status / list
the current download / every entry
retry URL
put an entry back (r in the window)
forget URL
take one out; the downloaded file stays (d)
clear
forget finished and failed entries; files and log stay
cookies
retry the entries waiting on a sign-in (c)
--mp4
keep the video file, write no capture
--sstr
keep a Static Stream capture, remove the video once checked
--both
keep the two
--run / --no-run
start a runner this once / never

Notes

  • Nothing downloads until something runs the queue: ytq run, the window, or autostart (~/.config/ytq/auto). Without that file, clip and add only queue.
  • A login, age gate or "confirm you are not a bot" page opens Brave on the URL: sign in there, then ytq cookies. A second failure is final.
  • What it keeps by default is a .sstr capture, not a video file. sstr export DIR turns a folder of them back into ordinary files.
  • The log is ~/.local/share/ytq/ytq.log; the queue is ~/.local/share/ytq/queue.json.

See also sstr, sstr-workspace, copal-build

Control

redshift Warm the screen's colour after sunset, following the time of day at your location.

Control · command-line tool · redshift 1.12 · stage 12 · The application catalogue · man redshift(1) · home

needs python3, libx11, libxxf86vm, libdrm, glib, libxcb

On Copal: The catalogue's night colour for the X11 desktop (i3). It has no Wayland method, so on Hyprland it cannot reach the screen; there, hyprsunset and gammastep -- installed with it as optionals -- do the same job.

redshift [-l LAT:LON | -l PROVIDER:OPTIONS] [-t DAY:NIGHT] [OPTIONS...]

Use

Give it your latitude and longitude; it shifts the colour temperature through the day. -O sets one temperature and leaves it; -x resets.

Examples

redshift -l 51.5:-0.1follow the sun at London (runs until stopped)
redshift -l 51.5:-0.1 -t 6500:3500daytime and night temperatures
redshift -O 4000one warm setting, now
redshift -xback to normal
redshift -m listthe methods this build has

Options

-l LAT:LON
your location
-t DAY:NIGHT
colour temperatures (default 6500:4500)
-O TEMP
one-shot: set TEMP and exit
-o
one-shot: set the current temperature and exit
-x
reset the screen
-P
reset the gamma first (for -O)
-m METHOD
randr, vidmode or drm

Notes

  • On Hyprland it has nothing to talk to: this build's methods are X11's (randr, vidmode) and bare DRM. Use hyprsunset -t 4000, Hyprland's own, or gammastep, redshift's Wayland-capable fork with the same options.
  • Settings can live in ~/.config/redshift/redshift.conf instead of on the command line.

See also hyprctl

udiskie Mount USB sticks and cards automatically when they are plugged in, with a tray icon.

Control · command-line tool · udiskie 2.6.1 · stage 12 · The application catalogue · man udiskie(8) · home

needs py3-docopt, py3-keyutils, py3-gobject3, py3-yaml, python3, udisks2

On Copal: The catalogue's automounter: plug in a stick and it appears under /run/media, with a notification -- no mount commands. It talks to udisks2, which starts on demand.

udiskie [OPTIONS]

udiskie-mount [OPTIONS] (-a | DEVICE...)

udiskie-umount [OPTIONS] (-a | PATH...)

Use

Run it in the background of the desktop session; it mounts removable media as it arrives and offers to unmount from its tray icon. For a one-off, udisksctl mounts and unmounts by hand.

Examples

udiskie -a -n -t &automount, notify, tray icon
udiskie -a -n -s &the icon only while something is mounted
udisksctl mount -b /dev/sda1mount one partition by hand
udisksctl unmount -b /dev/sda1and unmount it
udisksctl statusthe drives udisks2 sees

Options

-a, --automount
mount new devices as they appear
-n, --notify
show a notification for each
-t, --tray
show a tray icon
-s, --smart-tray
the tray icon only while there is something to show
-N, --no-notify
no notifications
-T, --no-tray
no tray icon

Notes

  • To start it with the desktop, add exec-once = udiskie -a -n -s to ~/.config/hypr/local.conf.
  • Media are mounted under /run/media/$USER/LABEL; unmount before pulling a stick out, or the last writes may not reach it.

See also lsblk, sshfs

Design

dot Graphviz: lay out and draw graphs -- boxes and arrows -- from a text description.

Design · command-line tool · graphviz 12.2.1 · stage 12 · The application catalogue · man dot(1) · home

needs font-cantarell, libx11, cairo, graphviz-libs, libexpat, libgd, glib, pango

On Copal: The catalogue's graph drawer, and the layout engine PlantUML and Doxygen call. A dependency tree, a state machine or a network map is a few lines of text.

dot [options] [files]
neato [options] [files]
twopi [options] [files]
circo [options] [files]
fdp [options] [files]
sfdp [options] [files]
patchwork [options] [files]
osage [options] [files]

Use

Describe the graph in the DOT language -- nodes and -> edges -- and dot works out where everything goes and draws it. Other layouts of the same file: neato and fdp (springs), circo (circles), twopi (rings).

Examples

echo 'digraph { a -> b; a -> c; b -> d }' | dot -Tsvg > g.svgquick
dot -Tpng deps.dot -o deps.pnga file, as PNG
dot -Tpdf deps.dot -o deps.pdfas PDF
neato -Tsvg net.dot -o net.svgthe spring layout instead
dot -Tsvg -Grankdir=LR g.dot -o g.svgleft to right, not top down

Options

-T FORMAT
svg, png, pdf, and others
-o FILE
the output file (default stdout)
-G NAME=VALUE
a graph attribute: rankdir=LR, bgcolor=transparent
-N NAME=VALUE
a default for every node: shape=box
-E NAME=VALUE
a default for every edge
-K LAYOUT
the layout engine: dot, neato, fdp, circo, twopi

Notes

  • digraph draws arrows (->), graph plain lines (--); mixing them is a syntax error.
  • Large graphs are slow with dot; sfdp handles thousands of nodes.

See also plantuml, doxygen

plantuml Draw UML and other diagrams from plain text: sequence, class, state, activity, Gantt.

Design · command-line tool · plantuml 1.2025.10 · stage 12 · The application catalogue · home

needs graphviz, gtk+2.0, java-common, java-jre

On Copal: The catalogue's diagrams-as-text tool: a diagram kept as a few lines in the repository, diffed and reviewed like code, and drawn when needed.

Usage:
  java -jar plantuml.jar [options] [file|dir]...
  java -jar plantuml.jar [options] --gui

Use

Write the diagram between @startuml and @enduml in a .puml file, and run plantuml on it: a picture of the same name appears beside it. It is a Java program, so the first run takes a few seconds.

Examples

printf '@startuml\nAlice -> Bob: hello\n@enduml\n' > hi.puml
plantuml hi.pumlhi.png
plantuml -tsvg hi.pumlhi.svg instead
plantuml --svg --output-dir out docs/every diagram in docs/, into out/
cat hi.puml | plantuml -tsvg -pipe > hi.svgstdin to stdout
plantuml --check-syntax docs/check without drawing

Options

--svg / --png
the output format
--output-dir DIR
where the pictures go
-pipe
read stdin, write the picture to stdout
--check-syntax
check the diagrams, draw nothing
--gui
a window listing the diagrams in a folder

Notes

  • -tsvg and -tpng, the older spellings most guides use, still work.
  • Class and component diagrams are laid out by Graphviz, which is installed (dot); sequence diagrams need nothing else.
  • On a Pi with little memory, Java's start-up is most of the time. Draw a whole folder in one run rather than a file per run.

See also dot, nvim

Desktop

hyprctl Ask the running Hyprland about its windows, monitors and settings, and change them.

Desktop · hyprland 0.54.3 · stage 17 · Hyprland and the Antiquity theme · man hyprctl(1) · home

needs mesa-egl, mesa-gles, libxcursor, aquamarine, cairo, libdrm, mesa-gbm, glib

On Copal: Stage 17's desktop is Hyprland. hyprctl is how to find a monitor's name, a window's class for a rule, or why a line in the config was not accepted -- and to try a setting before writing it down.

hyprctl [(opt)flags] [command] [(opt)args]

Use

Query (monitors, clients, activewindow), or act (dispatch, keyword, reload). A keyword change lasts until the next reload; to keep it, put the same line in ~/.config/hypr/local.conf.

Examples

hyprctl monitors allevery output, its name and modes
hyprctl clientsevery window: class, title, workspace
hyprctl activewindowthe focused one (click it first)
hyprctl configerrorswhat the config got wrong
hyprctl reloadre-read the config
hyprctl dispatch workspace 3do what a key would do
hyprctl keyword general:gaps_out 0change a setting until the next reload
hyprctl -j clientsthe same as JSON, for a script

Options

monitors [all]
outputs; all includes the disabled ones
clients
windows
activewindow
the focused window
workspaces
workspaces and what is on them
binds
every key binding
configerrors
config lines that failed
reload
reload the configuration
dispatch NAME ARGS
run a dispatcher: workspace, exec, killactive...
keyword NAME VALUE
set a config value for now
-j
JSON output
--batch 'A; B'
several commands in one call

Notes

  • ~/.config/hypr/hyprland.conf is rewritten each time stage 17 runs. Your changes go in local.conf, which it sources last, so they win; Hyprland reloads on save.
  • Hyprland 0.54 reads only the .conf dialect. The hyprland.lua beside it is upstream's original, for 0.55 and later.
  • A window rule needs the window's class: open it, then hyprctl clients and read class:.

See also copal-desk, copal-theme, copal-shot

Development

gcc The GNU C and C++ compiler.

Development · gcc 15.2.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man gcc(1) · home

needs binutils, libgcc-static, libgomp, libatomic, gmp, isl25, mpc1, mpfr4

On Copal: Stage 7 installs build-base -- gcc, make and the musl headers -- because most things built on a Copal machine start here: the checkouts in ~/code, the store's source builds, your own programs.

gcc [-c|-S|-E] [-std=standard]
    [-g] [-pg] [-Olevel]
    [-Wwarn...] [-Wpedantic]
    [-Idir...] [-Ldir...]
    [-Dmacro[=defn]...] [-Umacro]
    [-foption...] [-mmachine-option...]
    [-o outfile] [@file] infile...

Only the most useful options are listed here; see below for the remainder.  g++ accepts
mostly the same options as gcc.

Use

Compile C (gcc) or C++ (g++) source into a program, or into object files for a larger build. Warnings on and debug information in is the right default while writing; optimisation for the version you keep.

Examples

gcc -Wall -Wextra -g hello.c -o hellocompile, warnings on, debuggable
./hellorun it
gcc -O2 -o hello hello.coptimised
g++ -std=c++20 -Wall main.cpp -o mainC++, a chosen standard
gcc -c util.cobject file only, for linking later
gcc main.o util.o -lm -o proglink, with the maths library
gcc -static hello.c -o helloone file, no shared libraries
cd ~/dev/hello && make runCopal's sample project

Options

-o FILE
name the output
-c
compile only, make a .o
-g
debug information, for gdb
-O2
optimise; -O0 for none, -Os for size
-Wall -Wextra
the warnings worth having
-std=c17
the language standard: c89 c99 c11 c17 c23, c++17 c++20 c++23
-I DIR
another directory of headers
-L DIR -lNAME
link libNAME from DIR
-static
link everything in
-E
preprocess only

Notes

  • The C library is musl, not glibc. Code that uses glibc extensions (execinfo.h's backtrace, some _GNU_SOURCE corners) will not find them. A binary built on Debian will not run here, nor the reverse.
  • -fsanitize=address and -fsanitize=undefined fail to link: Alpine ships no sanitizer runtimes. Use valgrind for memory errors.
  • -static is cheap and reliable on musl -- a static binary copies to another Copal machine of the same architecture and runs.
  • Missing header? The library's -dev package has it: apk add openssl-dev for openssl/ssl.h.

See also clang, make, gdb, valgrind, cmake

git Version control: keep a project's history, branch it, and share it.

Development · git 2.54.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man git(1) · home

needs libcurl, libexpat, pcre2, zlib

On Copal: Stage 7 clones your repositories into ~/code with it, and sets its identity from the answers given on the Mac. copal-code pulls and rebuilds every checkout through it; Copal itself is a git checkout.

git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
    [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
    [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-lazy-fetch]
    [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]
    [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>]
    <command> [<args>]

Use

Record changes as commits, move between versions, and exchange them with a remote such as GitHub. The daily loop is short: status, add, commit, pull, push.

Examples

git statuswhat changed, what is staged
git add -pstage changes a piece at a time
git commit -m 'Fix the menu order'record them
git pull --rebasebring in others' work, yours on top
git pushsend your commits
git log --oneline --graph -20recent history as a tree
git diff HEAD~1what the last commit changed
git switch -c try-thisa new branch, and onto it
git restore file.cthrow away uncommitted edits to a file

Options

status
the working tree against the last commit
add -p
stage hunk by hunk, asking for each
commit -m MSG
commit with a message; --amend to redo the last one
pull --rebase
fetch, then replay your commits on top
log --oneline
one line per commit; --graph draws the branches
diff / diff --staged
unstaged / staged changes
switch -c NAME
create a branch and switch to it
restore FILE
discard working-tree changes; --staged to unstage
stash / stash pop
set changes aside, and bring them back
remote -v
where fetch and push go

Notes

  • Stage 7 clones over SSH when it can and over HTTPS when it cannot. HTTPS checkouts pull but cannot push without a token: make a key (ssh-keygen -t ed25519), add its .pub to GitHub, then git remote set-url origin git@github.com:you/thing.git.
  • The identity comes from stage 1's answers: git config --global user.email shows it, and sets it.
  • git restore and git reset --hard discard work with no undo. When unsure, git stash first: it keeps the changes where you can get them back.
  • With delta installed (the catalogue's System section), git config --global core.pager delta makes diffs coloured and clearer.

See also ssh-keygen, ssh, make, copal-code, copal-build

make Rebuild what is out of date, by the rules in a Makefile.

Development · make 4.4.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man make(1) · home

On Copal: The build tool behind Neovim's F5 (:make) and stage 7's sample project in ~/dev/hello, and the front door of most checkouts -- Copal's own repository included (make lint, make commands).

make [OPTION]... [TARGET]...

Use

Run in a directory with a Makefile: make builds its first target, make NAME a named one. It compares file times, so only what changed is rebuilt.

Examples

makebuild the default target
make -j4four jobs at once (a Pi 4 has four cores)
make runa named target: build, then run
make cleanremove what was built
make -nprint the commands, run none
make -C ~/dev/hellorun it in another directory
make CC=clang CFLAGS='-O2 -g'override a variable for this run

Options

-j N
run N jobs in parallel
-n
dry run: show the commands
-C DIR
change to DIR first
-B
rebuild everything, dated or not
-k
keep going after an error
-s
silent: do not echo the commands
VAR=VALUE
set a variable, overriding the Makefile's

Notes

  • Recipe lines start with a TAB, not spaces. "missing separator" means an editor put spaces there.
  • -j with more jobs than RAM can hold: on a 512 MB board, make -j1 and zram are safer than a build killed halfway.
  • In Neovim, F5 saves and runs :make; the errors land in the quickfix list, and ]q and [q walk them.

See also gcc, cmake, ninja, nvim

ninja Run a build that cmake or meson generated, fast and in parallel.

Development · samurai 1.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ninja(1) · home

On Copal: The builder behind cmake -G Ninja and every meson project. On Alpine the command is samurai, a small compatible reimplementation (/usr/bin/samu); what it lacks, few builds use.

samu [-C dir] [-d debugflag] [-f buildfile] [-j maxjobs] [-k maxfail] [-w warnflag=action]
     [-nv] [target...]
samu [-C dir] [-f buildfile] -t clean [-gr] [target...]
samu [-C dir] [-f buildfile] -t compdb [-x] [rule...]
samu [-C dir] [-f buildfile] -t commands [target...]
samu [-C dir] [-f buildfile] -t query [target...]
samu [-C dir] [-f buildfile] -t targets [depth [maxdepth]]
samu [-C dir] [-f buildfile] -t targets rule [rulename]
samu [-C dir] [-f buildfile] -t targets all
samu -t list

Use

Run it in (or point it at) a build directory that has a build.ninja. You rarely write that file yourself: cmake or meson writes it, and ninja builds from it, running as many jobs as there are cores.

Examples

ninja -C buildbuild in ./build
ninja -C build -j2two jobs (a small board's RAM)
ninja -C build -vshow every command
ninja -C build -t cleanremove what it built
ninja -C build -t targetswhat can be built
ninja -C build -t compdb > compile_commands.jsonfor clangd

Options

-C DIR
change to DIR first
-j N
N jobs at once (default: cores + 2)
-k N
keep going until N failures
-n
dry run
-v
print each full command
-t TOOL
a subtool: clean, targets, commands, compdb, query

Notes

  • It is samurai: -t graph and a few other ninja subtools are not there ("unknown tool"). Builds themselves behave the same.
  • The default job count assumes enough memory for each. On a 512 MB Pi, a C++ build at -j3 swaps hard; pass -j1 or -j2.
  • Do not edit build.ninja: the next cmake or meson run rewrites it.

See also cmake, make, meson

nvim Neovim: a modal text editor, set up by Copal as a small IDE.

Development · neovim 0.12.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man nvim(1) · home

needs lua5.1-lpeg, tree-sitter-c, tree-sitter-lua, tree-sitter-markdown, tree-sitter-vim, tree-sitter-vimdoc, tree-sitter-query, libintl

On Copal: Stage 7's editor. Copal's configuration gives it building (F5), the error list, a debugger (F4), language servers and LazyVim-shaped keys -- with no plugin manager and nothing to download.

nvim [options] [file ...]
nvim [options] -
nvim [options] -t tag
nvim [options] -q [errorfile]

Use

Open a file, edit in insert mode, move and change text in normal mode. On a Copal machine it also builds and debugs: F5 runs make, the errors land in a list, and the language server answers "where is this defined" and "who calls this". Space is the leader key: press it and wait for the menu of what follows.

Examples

nvim main.copen a file
nvim +42 main.cat line 42
nvim -d old.c new.cside-by-side diff
copal-guide nvimCopal's tutorial, from nothing to useful
F5 (in nvim) save and build; ]q / [q walk the errors
gd gr K go to definition / references / documentation
Space ci who calls this function
F9 F4 breakpoint here / start the debugger
Ctrl-O back to where you jumped from
:Lsp which language servers this machine has

Options

+N
open at line N
-d A B
diff mode
-R
read-only
--clean
start with no configuration at all (to test a problem)
:w
:q :wq (in nvim) write, quit, both; :q! quits without saving
i
Esc (in nvim) into insert mode, back to normal mode
u
Ctrl-R (in nvim) undo, redo

Notes

  • The configuration is layered, and one part is yours: ~/.config/nvim/local.lua is never written by Copal and runs last. init.vim, theme.lua, keys.lua and lsp.lua are rewritten when stage 7 runs again.
  • Language servers need the project's build flags for C and C++: a compile_commands.json, from bear -- make or cmake.
  • The colours follow the desktop's theme, even in a running editor.
  • :Tutor inside nvim is the half-hour lesson in the modal part.

See also make, gdb, git, tmux, clang

pip Install Python packages from PyPI -- inside a virtual environment.

Development · py3-pip 26.1.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man pip(1) · home

needs python3

On Copal: Stage 7 installs it for the packages Alpine does not carry. On Alpine it refuses to touch the system's Python, and that refusal is the most-asked question about it.

pip <command> [options]

Use

Make a virtual environment for the project, enter it, and pip installs there -- not into the system. For a command-line tool you want everywhere, pipx does the same for one program at a time.

Examples

apk search -e py3-requestsfirst: does apk have it?
python3 -m venv .venv && . .venv/bin/activatea venv, entered
pip install requestsinto the venv
pip install -r requirements.txta project's list
pip freeze > requirements.txtwrite that list
pip list --outdatedwhat could be upgraded
doas apk add pipx && pipx install yt-dlpa tool, in its own venv, on PATH

Options

install PKG
install; -U to upgrade; ==VER for a version
install -r FILE
install every line of FILE
uninstall PKG
remove
list
what is installed; --outdated
show PKG
version, location, dependencies
freeze
installed packages as a requirements file

Notes

  • "error: externally-managed-environment" outside a venv is Alpine protecting apk's Python. --break-system-packages overrides it and means what it says: a later apk upgrade can break both.
  • A package with C inside may have no musl wheel and compile instead, which needs build-base python3-dev and, on a Pi, patience.
  • pip install --user is refused too. pipx is the tool for per-user programs; it puts them in ~/.local/bin, which Copal puts on PATH.

See also python3, apk

Devtools

bear Record a build's compiler calls into compile_commands.json, for clangd and other tools.

Devtools · command-line tool · bear 4.1.5 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man bear(1) · home

On Copal: The catalogue's bridge between a Makefile and the editor: clangd needs each file's flags, and a plain make build does not write them down. Bear watches the build and does.

bear [OPTIONS] [--] [BUILD_COMMAND...]

bear intercept [OPTIONS] [--] BUILD_COMMAND...

bear semantic [OPTIONS]

Use

Put bear -- in front of the build command. Afterwards compile_commands.json sits in the current folder, and clangd -- in Neovim, Helix or Geany -- understands the project.

Examples

bear -- makerecord a make build
make clean && bear -- make -j4a full rebuild, so every file is seen
bear --append -- make extraadd to an existing file
bear --output build/cc.json -- makewrite it somewhere else

Options

--
everything after is the build command
--output FILE
where to write (default compile_commands.json)
--append
add to the file instead of replacing it

Notes

  • Only files that are compiled during the run are recorded: after a make that had nothing to do, the file is empty. Clean first.
  • CMake and Meson write the same file themselves; Bear is for builds that do not.

See also clangd, make, cmake

ccache A compiler cache: a rebuild of unchanged code takes seconds instead of minutes.

Devtools · command-line tool · ccache 4.13.6 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ccache(1) · home

needs hiredis, libxxhash, zstd-libs

On Copal: The catalogue's rebuild accelerator -- worth most on a Pi, where compiling is slow and the same sources are often built again after a make clean or a branch switch.

ccache [ccache options]
ccache [KEY=VALUE ...] compiler [compiler options]
compiler [compiler options]

The first form takes options described in COMMAND LINE OPTIONS below. The second form invokes
the compiler, optionally using configuration options as KEY=VALUE arguments. In the third
form, ccache is masquerading as the compiler as described in RUN MODES.

Use

Put it in front of the compiler. It remembers each compilation's result by its inputs; the same file with the same flags later comes from the cache. It is not switched on by default.

Examples

CC="ccache gcc" makeone build, through the cache
export PATH=/usr/lib/ccache/bin:$PATHevery gcc/cc call, from now on
cmake -B build -DCMAKE_C_COMPILER_LAUNCHER=ccachefor a CMake project
ccache -shits, misses and cache size
ccache -Cempty the cache

Options

-s, --show-stats
statistics: hits, misses, size
-z, --zero-stats
reset the statistics
-C, --clear
empty the cache
-M, --max-size SIZE
set the cache limit, e.g. 5G
-p, --show-config
the settings in force

Notes

  • The cache is ~/.cache/ccache, 5 GB at most by default; on a small card, ccache -M 1G.
  • /usr/lib/ccache/bin holds links named gcc, cc, g++ and the rest, which is what makes the PATH method cover everything.

See also gcc, clang, make, cmake

cgdb gdb with a source window above it, in the terminal: see the code as you step.

Devtools · terminal program · cgdb 0.8.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs gdb, libncursesw, readline

On Copal: The catalogue's lightweight debugging front end: gdb's commands, with the current line shown in the source -- the simplest way to see where a program is, over SSH or on a console.

Use

Start it as you would gdb. The top half shows the source with the current line marked; the bottom half is gdb itself. Escape moves to the source window, i back to gdb.

Examples

cgdb ./progdebug a program
cgdb -- --args ./prog -v in.txtgdb options after --
cgdb -d gdb-multiarch ./arm-binarywith another gdb
Esc (in cgdb) to the source window: vi keys to move, / to search
Space (source window) set or clear a breakpoint on this line
i back to the gdb window
break / run / next / step / print (gdb window) as in gdb

Options

-d DEBUGGER
the gdb to run
--
the rest goes to gdb

Notes

  • Build with -g: without debug information there is no source to show.
  • Its settings go in ~/.config/cgdb/cgdbrc (for example set syntax=on, or a colour scheme).

See also gdb, lldb, pwndbg

cl65 Compiler Suite for 6502 based processors

Devtools · command-line tool · cc65 2.19 · stage 12 · The application catalogue · home

No notes yet: the facts above are read from apk and the man page.

cmake Generate a project's build files -- for ninja or make -- from its CMakeLists.txt.

Devtools · command-line tool · cmake 4.2.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man cmake(1) · home

needs libarchive, libcrypto3, libexpat, rhash-libs, libssl3, libuv, zlib

On Copal: Stage 7 installs it because a large share of C and C++ projects build only through it; several of the store's source builds do.

Generate a Project Buildsystem
 cmake [<options>] -B <path-to-build> [-S <path-to-source>]
 cmake [<options>] <path-to-source | path-to-existing-build>

Build a Project
 cmake --build <dir> [<options>] [-- <build-tool-options>]

Install a Project
 cmake --install <dir> [<options>]

Open a Project
 cmake --open <dir>

Run a Script
...

Use

Two steps, always in a separate build directory: configure (read CMakeLists.txt, find the compiler and libraries, write the build files), then build. Configure once; after that, only the build step.

Examples

cmake -B build -G Ninjaconfigure into ./build, for ninja
cmake --build buildbuild (runs ninja or make for you)
cmake --build build -j4with four jobs
cmake -B build -DCMAKE_BUILD_TYPE=Releaseoptimised
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ONfor clangd in nvim
doas cmake --install buildinstall to /usr/local
cmake -B build --freshreconfigure from nothing

Options

-B DIR
the build directory (made if missing)
-S DIR
the source directory (default: here)
-G NAME
the generator: Ninja, or "Unix Makefiles"
-D VAR=VALUE
set a cache variable: CMAKE_BUILD_TYPE, CMAKE_INSTALL_PREFIX...
--build DIR
build a configured tree
--install DIR
install it
--fresh
forget the cached configuration
-j N
with --build: parallel jobs

Notes

  • The cache remembers. A changed compiler or a library installed after the first configure is not noticed until --fresh or rm -rf build.
  • "Could NOT find Foo": install the library's -dev package (apk search -e foo-dev), then configure again with --fresh.
  • CMAKE_BUILD_TYPE is empty by default: no optimisation and no debug information. Say Debug or Release.

See also ninja, make, gcc, clang

cppcheck Static analysis for C and C++: find bugs the compiler does not warn about.

Devtools · command-line tool · cppcheck 2.21.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man cppcheck(1) · home

needs pcre, tinyxml2

On Copal: The catalogue's C checker: out-of-bounds indexes, leaks, null pointers and uninitialised variables, found by reading the code, without running it.

cppcheck [--check-config] [--check-library] [-D<id>] [-U<id>] [--disable=<id>]
         [--enable=<id>] [--error-exitcode=<n>] [--errorlist] [--exitcode-suppress=<spec>]
         [--exitcode-suppressions=<file>] [--file-list=<file>] [--filesdir] [--force]
         [--fsigned-char] [--funsigned-char] [--help] [-I<dir>] [--includes-file=<file>]
         [--config-exclude=<dir>] [--config-excludes-file=<file>] [--include=<file>]
         [-i<dir>] [--inconclusive] [--inline-suppr] [-j<jobs>] [-l<load>]
         [--language=<language>] [--library=<cfg>] [--max-configs=<limit>]
         [--max-ctu-depth=<limit>] [--platform=<type>] [--quiet] [--relative-paths=<paths>]
         [--report-progress] [--report-type=<type>] [--rule=<rule>] [--rule-file=<file>]
         [--showtime=<mode>] [--std=<id>] [--suppress=<spec>] [--suppressions-list=<file>]
         [--suppress-xml=<.xml file>] [--template='<text>'] [--verbose] [--version] [--xml]
         [--xml-version=<version>]] [file or path] ...

Use

Point it at files or a folder. By default it reports only errors it is sure of; --enable widens it to warnings, style and performance.

Examples

cppcheck src/errors only
cppcheck --enable=all src/warnings, style, performance too
cppcheck --enable=warning,performance --std=c17 src/
cppcheck --project=compile_commands.jsonwith the real flags, from bear or cmake
cppcheck --xml src/ 2> report.xml && cppcheck-htmlreport --file=report.xml --report-dir=html

Options

--enable=LIST
warning, style, performance, portability, all
--std=STD
the language standard: c11, c17, c++17...
--project=FILE
read files and flags from compile_commands.json
-I DIR
an include directory
--suppress=ID
silence one kind of message
-j N
use N threads
--xml
XML output, for the HTML report

Notes

  • --enable=all also reports missingInclude for system headers; --suppress=missingIncludeSystem quiets it.
  • cppcheck-gui and cppcheck-htmlreport come with its optionals.

See also gcc, clang, valgrind

ctags Universal Ctags: index a project's definitions, so an editor can jump to them.

Devtools · command-line tool · ctags 6.2.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ctags(1) · home

needs jansson, yaml

On Copal: Stage 7 installs it: the tags file lets vim and Neovim jump to a function's definition in any language, even where no language server exists.

ctags [<options>] [<source_file(s)>]
etags [<options>] [<source_file(s)>]

Use

Run it at the top of a project; it writes a tags file. In vim or Neovim, Ctrl-] on a name jumps to where it is defined, Ctrl-T jumps back.

Examples

ctags -R .index the whole project into ./tags
ctags -R --exclude=build .leaving out a folder
ctags --list-languagesthe languages it knows
ctags -x --kinds-c=f main.cthe functions in one file, as a table

Options

-R
recurse into folders
--exclude=PATTERN
leave matching paths out
-f FILE
write to FILE instead of ./tags
--languages=LIST
index only these languages
--list-languages
list the languages
-x
print a cross-reference table instead of a file

Notes

  • Re-run it after large changes: the tags file does not update itself.
  • Add tags to .gitignore; it is generated, and large.

See also nvim, vim, clangd

doxygen Generate reference documentation -- HTML, with call graphs -- from comments in source code.

Devtools · command-line tool · doxygen 1.17.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man doxygen(1) · home

On Copal: The catalogue's API documenter for C, C++ and more: comments above functions become a browsable site, with diagrams drawn by Graphviz.

Use

Make a configuration file once with -g, set the project's name and input folder in it, then run doxygen: the site appears in html/.

Examples

doxygen -gwrite a Doxyfile with every setting explained
doxygenbuild from ./Doxyfile
doxygen -g - | grep -E '^(INPUT|RECURSIVE) 'the settings to look at first
xdg-open html/index.htmlread the result

Options

-g [FILE]
write a template configuration (default Doxyfile)
-u [FILE]
update an old configuration to this version
-s
with -g or -u: leave out the explanatory comments

Notes

  • Out of the box it documents only commented items; EXTRACT_ALL = YES in the Doxyfile lists everything.
  • HAVE_DOT = YES turns on call and include graphs, drawn with Graphviz, which is installed.
  • Comments it reads start with /** or ///.

See also dot, mdbook

gdb The GNU debugger: stop a program, step through it, look at its state.

Devtools · terminal program · gdb 16.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man gdb(1) · home

needs musl-dbg, libdebuginfod, libexpat, gmp, xz-libs, mpfr4, libncursesw, python3

On Copal: Stage 7 installs it for C, C++, Rust and Go, and Neovim's F4 (Termdebug) is gdb in a split window. When a program crashes, gdb says where and why.

gdb [OPTIONS] [prog|prog procID|prog core]

Use

Start the program under gdb, set a breakpoint, run, and when it stops, look: the call stack, the variables, the next line. Build with -g first, or there is nothing to see but addresses.

Examples

gdb ./progload it, then type commands
gdb --args ./prog -v input.txtwith its arguments
gdb -q -ex run -ex bt ./progrun, and on a crash show the stack
gdb --tui ./progsource in a pane above the prompt
doas gdb -p $(pidof prog)attach to a running process
break main(inside gdb) stop at a function, or file.c:42
runstart it
next / stepthe next line / into the call
print xa variable's value
btthe call stack
continuerun on to the next stop

Options

--args PROG ARGS
pass arguments to the program
-p, --pid PID
attach to a running process
--core FILE
examine a core dump
--tui
the text interface: source, prompt, registers
-q
no banner
-ex CMD
run a gdb command at start; repeatable

Notes

  • Attaching to a process needs doas: ptrace is limited to a process's own children here (kernel.yama.ptrace_scope is 1).
  • Core dumps are off (ulimit -c is 0). ulimit -c unlimited in the shell first, and a crash leaves core beside the program.
  • In Neovim: F9 sets a breakpoint on the current line, F4 opens Termdebug, F8 / F10 / F11 continue, step over, step into.
  • For Rust, rust-gdb prints Rust types properly; Go is better served by dlv.

See also gcc, valgrind, nvim, cgdb, lldb

just A command runner: a project's recipes -- build, test, deploy -- in a justfile.

Devtools · command-line tool · just 1.48.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man just(1) · home

On Copal: The catalogue's make for tasks rather than files: named recipes, arguments, and no tabs-versus-spaces trap.

just [--alias-style] [--allow-missing] [--ceiling] [--check] [--chooser] [--clear-shell-args]
[--color] [--command-color] [--cygpath] [--dotenv-filename] [-E|--dotenv-path] [-n|--dry-run]
[--dump-format] [--explain] [-g|--global-justfile] [--group] [--highlight] [-f|--justfile]
[--list-heading] [--list-prefix] [--list-submodules] [--no-aliases] [--no-deps] [--no-dotenv]
[--no-highlight] [--one] [-q|--quiet] [--set] [--shell] [--shell-arg] [--shell-command]
[--changelog] [--choose] [-c|--command] [--completions] [--dump] [-e|--edit] [--evaluate]
[--fmt] [--groups] [--init] [--json] [-l|--list] [--man] [-s|--show] [--summary] [--usage]
[--variables] [--tempdir] [--timestamp] [--timestamp-format] [-u|--unsorted] [--unstable]
[-v|--verbose]... [-d|--working-directory] [--yes] [-h|--help] [-V|--version] [ARGUMENTS]

Use

Write recipes in a justfile; just NAME runs one, just runs the first. Each recipe is a list of shell lines.

Examples

just --listthe recipes here
justthe default (first) recipe
just testone recipe
just deploy piwith an argument
just --dry-run buildwhat it would run

Options

-l, --list
list the recipes
-n, --dry-run
print the commands, run nothing
-f, --justfile F
use another justfile
--choose
pick a recipe from a list
-v
print each command as it runs

Notes

  • A justfile recipe: a name and a colon, then the lines indented under it -- spaces or tabs, either works.
  • Unlike make, just does not compare file times: a recipe always runs.

See also make

lldb LLDB Documentation

Devtools · terminal program · lldb 22.1.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man lldb(1) · home

needs musl-dbg, llvm22-libs, clang22-libs, libcurl, libedit, xz-libs, libncursesw, libpanelw

lldb [options] executable

No notes yet: the facts above are read from apk and the man page.

ltrace Watch the library calls a program makes: what it asks of libc and other libraries.

Devtools · command-line tool · ltrace 0.7.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ltrace(1) · home

needs libelf

On Copal: strace's companion one level up: where strace shows the kernel calls, ltrace shows malloc, strcmp, getenv and the rest -- which settings a program reads and what it compares.

ltrace [-e filter|-L] [-l|--library=library_pattern] [-x filter] [-S] [-b|--no-signals] [-i]
[-w|--where=nr] [-r|-t|-tt|-ttt] [-T] [-F filename] [-A maxelts] [-s strsize] [-C|--demangle]
[-a|--align column] [-n|--indent nr] [-o|--output filename] [-D|--debug mask] [-u username]
[-f] [-p pid] [[--] command [arg ...]]

ltrace -c [-e filter|-L] [-l|--library=library_pattern] [-x filter] [-S] [-o|--output
filename] [-f] [-p pid] [[--] command [arg ...]]

ltrace -V|--version

ltrace -h|--help

Use

Run a program under it; each call into a shared library prints with its arguments and return value. -c counts them instead.

Examples

ltrace ./progevery library call
ltrace -c ./proga count of calls, and their time
ltrace -e getenv ./progwhich environment variables it reads
ltrace -f -o calls.txt ./progchildren too, into a file

Options

-c
count calls instead of printing them
-e FILTER
only these calls
-f
follow child processes
-o FILE
write to FILE
-p PID
attach to a running process
-S
system calls too

Notes

  • It sees calls into shared libraries only: a statically linked program shows nothing.
  • Attaching with -p needs root, like strace.

See also strace, gdb

lua-language-server The Lua language server: completion, types, and errors as you type, in any editor.

Devtools · command-line tool · lua-language-server 3.16.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

On Copal: Stage 7's server for Lua, which Neovim starts for .lua files -- the language Copal's own Neovim configuration is written in.

Use

The editor runs it; there is nothing to start by hand. From the shell, --check runs its diagnostics over a folder and reports what it finds.

Examples

lua-language-server --check=.the diagnostics for this folder
lua-language-server --check=. --check_format=prettyreadable, to stdout

Options

--check=DIR
run the diagnostics over DIR
--check_format=FMT
pretty (to stdout) or json (to a file)

Notes

  • In Neovim it warns that vim is an undefined global until told the code runs inside Neovim: a .luarc.json with {"diagnostics.globals": ["vim"]}.
  • A project's settings go in .luarc.json at its root.

See also lua5.4, nvim

meson A build system: configure a project into a build folder, then build it with ninja.

Devtools · command-line tool · meson 1.11.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man meson(1) · home

needs samurai, python3

On Copal: Stage 7's Meson, for the many C, C++ and GNOME projects that build with it -- several of Copal Apps' source builds among them.

Use

Two steps, as with CMake: meson setup configures into a build folder, meson compile (or ninja -C build) builds. Options are set at setup and changed later with meson configure.

Examples

meson setup buildconfigure into ./build
meson setup build --buildtype=releaseoptimised
meson compile -C buildbuild (runs ninja)
meson test -C buildthe tests
meson configure buildevery option and its value
meson configure build -Dfoo=enabledchange one

Options

setup DIR
configure into DIR
compile -C DIR
build
test -C DIR
run the tests
install -C DIR
install (doas for /usr/local)
configure DIR
show or change options (-Dname=value)
setup --buildtype=T
debug, debugoptimized, release
setup --reconfigure
set up again in an existing folder

Notes

  • meson setup prints which optional dependencies it found and which it did not: that list says which features the build will have.
  • It writes compile_commands.json in the build folder for clangd.

See also ninja, cmake, make

pwndbg Exploit Development and Reverse Engineering with GDB & LLDB Made Easy

Devtools · command-line tool · pwndbg 2026.02.18 · stage 12 · The application catalogue · home

needs python3, py3-capstone, py3-cparser, py3-elftools, py3-hatchling, py3-psutil, py3-pygments, py3-requests

No notes yet: the facts above are read from apk and the man page.

pylsp The Python language server: completion, go-to-definition and lint for Python, in any editor.

Devtools · command-line tool · py3-lsp-server 1.14.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs py3-docstring-to-markdown, py3-jedi, py3-lsp-jsonrpc, py3-pluggy, py3-setuptools, py3-ujson, py3-whatthepatch, py3-yapf

On Copal: Stage 7's server for Python, which Neovim and Helix start for .py files: definitions, references and hover documentation.

usage: pylsp [-h] [--tcp] [--ws] [--host HOST] [--port PORT]
             [--check-parent-process] [--log-config LOG_CONFIG |
             --log-file LOG_FILE] [-v] [-V]

Use

The editor runs it over stdin and stdout; there is nothing to start by hand. It finds modules as the Python it runs under does, so a project's virtual environment should be active when the editor starts.

Examples

pylsp --helpits options
. .venv/bin/activate && nvim app.pythe editor sees the venv's packages
pylsp -v --log-file /tmp/pylsp.loga verbose log, to see what it does

Options

--tcp
serve over TCP instead of stdio
--host / --port
where, with --tcp
--log-file FILE
write its log to FILE
-v
more detail in the log

Notes

  • Its checks come from plugins: pyflakes (errors) and pycodestyle (style), which Copal installs with it as optionals from 24 Sep 2026.
  • Settings are passed by the editor, not a file of its own.

See also python3, nvim, hx

shellcheck Find bugs in shell scripts: quoting, portability, and the traps sh is full of.

Devtools · command-line tool · shellcheck 0.11.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man shellcheck(1) · home

needs libffi, gmp

On Copal: The catalogue's shell linter, and the one Copal's own scripts are written against: most of Copal is POSIX sh, and shellcheck knows which sh a script says it is.

shellcheck [OPTIONS...]  FILES...

Use

Run it on a script; each finding has a code (SC2086 and so on), a line, and an explanation. The script's first line decides the dialect it checks: #!/bin/sh is held to POSIX, #!/bin/bash allows bash.

Examples

shellcheck script.shcheck one script
shellcheck -s sh script.shas POSIX sh, whatever its first line
shellcheck -x script.shfollow the files it sources
shellcheck -f diff script.sh | patch -p1apply the fixes it can make

Options

-s SHELL
check as sh, bash, dash or ksh
-x
follow sourced files
-e CODES
exclude these codes
-S LEVEL
minimum severity: error, warning, info, style
-f FORMAT
output format: tty, gcc, json, diff

Notes

  • A finding can be silenced for one line with a comment above it: # shellcheck disable=SC2086, with the reason beside it.
  • Every code has a page explaining it: search "shellcheck SC2086".

See also shfmt, busybox

shfmt Format shell scripts consistently -- and parse them, which catches syntax errors.

Devtools · command-line tool · shfmt 3.13.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man shfmt(1) · home

On Copal: The catalogue's shell formatter, shellcheck's partner: one style for every script in a project, applied by a command, not by hand.

shfmt [flags] [path...]

Use

With no options it prints the script reformatted. -d shows the changes as a diff, -w writes them back. Indentation and style are options.

Examples

shfmt -d script.shwhat it would change
shfmt -w script.shchange it in place
shfmt -i 4 -w *.shfour spaces of indent
shfmt -l .list the files that are not formatted
shfmt -p -d script.shhold it to POSIX sh

Options

-d
print a diff instead of the result
-w
write the result back to the file
-l
list files whose formatting differs
-i N
indent with N spaces (0 means tabs, the default)
-p
POSIX sh only (same as -ln posix)
-ln LANG
the dialect: bash, posix, mksh, bats
-ci
indent switch cases

Notes

  • A syntax error stops it with the line and column: shfmt -d doubles as a quick check that a script parses.
  • It reads an .editorconfig, so a project's indentation can live there instead of in options.

See also shellcheck

strace Watch the system calls a program makes: which files it opens, what fails, and why.

Devtools · command-line tool · strace 6.19 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man strace(1) · home

needs libdw

On Copal: The catalogue's answer to "it just says error": strace shows the file a program could not find, the permission it was refused, the address it could not reach.

strace [-ACdffhikkqqrtttTvVwxxyyYzZ] [-a column] [-b execve] [-e expr]... [-I n] [-o file]
       [-O overhead] [-p pid]... [-P path]... [-s strsize] [-S sortby] [-U columns]
       [-X format] [--seccomp-bpf] [--stack-trace-frame-limit=limit] [--syscall-limit=limit]
       [--tips[=format]] { -p pid | [-DDD] [-E var[=val]]... [-u username] command [args] }

strace -c [-dfwzZ] [-b execve] [-e expr]... [-I n] [-O overhead] [-p pid]... [-P path]...
       [-S sortby] [-U columns] [--seccomp-bpf] [--syscall-limit=limit] [--tips[=format]] {
       -p pid | [-DDD] [-E var[=val]]... [-u username] command [args] }

strace --tips[=format]

Use

Run a program under it, or attach to one running. Each system call prints as a line: the call, its arguments, and its result -- a failure shows its error name, such as ENOENT (no such file).

Examples

strace -f -e trace=openat ./prog 2>&1 | grep ENOENTfiles it looked for and missed
strace -c ls /a summary: which calls, how often, how long
strace -o trace.txt -f ./progeverything, into a file
strace -e trace=network curl -s example.com >/dev/nullits network calls
doas strace -p $(pidof prog)attach to a running process

Options

-f
follow child processes too
-e trace=SET
only these calls: openat, network, file, process...
-o FILE
write the trace to FILE
-c
count calls and time instead of printing them
-p PID
attach to a running process
-s N
show strings up to N characters (default 32)
-t / -T
timestamps / time spent in each call

Notes

  • Attaching to a process needs root (ptrace_scope is 1); tracing a program you start yourself does not.
  • strace-tui, one of its optionals, browses a saved trace file interactively.

See also ltrace, gdb, valgrind

valgrind Run a program under a checker that catches memory errors and leaks.

Devtools · command-line tool · valgrind 3.25.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man valgrind(1) · home

On Copal: On Alpine it is the memory checker: the compilers' AddressSanitizer runtime is not packaged. Stage 7 installs it where it exists -- everywhere but 32-bit ARMv6 (armhf).

valgrind [valgrind-options] [your-program] [your-program-options]

Use

Put valgrind in front of the command. The program runs perhaps twenty times slower, and every invalid read or write, use of freed memory and leak is reported with the line it came from -- if it was built with -g.

Examples

valgrind ./progmemory errors as they happen
valgrind --leak-check=full ./progand every leak, with where it was allocated
valgrind -q --leak-check=full --error-exitcode=1 ./progquiet; fail a test on error
valgrind --track-origins=yes ./progwhere an uninitialised value came from
valgrind --tool=callgrind ./progwhere the time goes, by function

Options

--leak-check=full
report each leak in detail
--show-leak-kinds=all
include "still reachable" blocks
--track-origins=yes
trace uninitialised values to their source (slower)
--error-exitcode=N
exit N if errors were found
--tool=NAME
memcheck (default), massif, callgrind, cachegrind, helgrind
-q
only the errors
--log-file=FILE
report to FILE instead of the terminal

Notes

  • Read the first error first. Later ones are often its consequences.
  • "definitely lost" is a real leak; "still reachable" is memory held at exit, usually harmless.
  • Build with -g -O0 (or -O1) for readable reports; optimised code reports lines that do not match the source.

See also gdb, gcc, clang

Discs

7z 7-Zip: pack and unpack .7z, zip, tar and more, and extract rar, iso and dozens of others.

Discs · command-line tool · 7zip 26.01 · stage 10 · Wireless, audio, capture and disks · home

On Copal: The catalogue's universal archiver: the best compression of the common formats, strong encryption, and it opens nearly any archive someone sends you -- rar included.

Usage: 7zz <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]
<Commands>
  a : Add files to archive

Use

A command letter, the archive, then files. x extracts with folders, a adds, l lists. It detects the format of what it opens.

Examples

7z x archive.rarextract, keeping folders
7z l archive.7zlist the contents
7z a backup.7z ~/Documentsa new .7z of a folder
7z a -p -mhe=on secret.7z plans/encrypted, names hidden too
7z x image.iso -oiso-filesthe files inside an ISO
7z t archive.ziptest it for damage

Options

a
add to an archive (creating it)
x
extract with full paths
e
extract everything into one folder
l
list
t
test integrity
-o DIR
extract into DIR (written -oDIR, no space)
-p
set or ask for a password
-mx=N
compression level, 0 to 9 -m{...} other method settings: -mhe=on encrypts the file names too (.7z)

Notes

  • The command here is 7z; guides that say 7za or 7zr mean the same program.
  • -o takes its folder with no space: -oout, not -o out.
  • It reads rar archives but cannot create them.

See also zip, bsdtar, unarj

abcde A Better CD Encoder: rip a CD, look up its track names, encode and tag, in one command.

Discs · command-line tool · abcde 2.9.3 · stage 12 · The application catalogue · man abcde(1) · home

needs bash, cd-discid, eyed3, perl-webservice-musicbrainz

On Copal: The catalogue's CD-to-music-library tool: cdparanoia to rip, a database lookup for the names, an encoder for FLAC, Ogg or MP3.

abcde [options] [tracks]

Use

Insert the CD and run it. It looks up the disc, asks you to confirm the names, rips every track and encodes them into folders by artist and album.

Examples

abcderip and encode, with the defaults
abcde -o flacto FLAC
abcde -o flac,oggtwo formats at once
abcde -N -o flacno questions (unattended)
abcde -c ~/.abcde.confwith your own settings

Options

-o FORMATS
output formats: flac, ogg, mp3, opus...
-N
non-interactive: accept the lookup's answer
-d DEV
the CD drive
-c FILE
another configuration file
-x
eject the CD when done

Notes

  • Settings go in ~/.abcde.conf: OUTPUTTYPE, OUTPUTDIR, the naming pattern.
  • Each format needs its encoder. Its default, Ogg, needs oggenc (vorbis-tools), which abcde does not pull in: the catalogue row brings it and flac from 24 Sep 2026. MP3 needs lame.
  • Not on 32-bit ARMv7: its row is gated off there.

See also cdparanoia, cmus

bsdtar libarchive's tar: reads almost any archive -- tar, zip, 7z, rar, iso, cpio, deb, rpm, xar.

Discs · command-line tool · libarchive-tools 3.8.7 · stage 12 · The application catalogue · man bsdtar(1) · home

needs acl-libs, libbz2, libcrypto3, libexpat, lz4-libs, xz-libs, zlib, zstd-libs

On Copal: The catalogue's universal unpacker. One command extracts whatever format someone sent, detecting it and its compression by itself.

tar [bundled-flags ⟨args⟩] [⟨file⟩ | ⟨pattern⟩ ...]
tar {-c} [options] [files | directories]
tar {-r | -u} -f archive-file [options] [files | directories]
tar {-t | -x} [options] [patterns]

Use

The tar options, on any format: -t lists, -x extracts, -c creates. Compression is detected when reading; when creating, -a picks it from the file name.

Examples

bsdtar -tf archive.ziplist any archive
bsdtar -xf image.iso -C out/extract, here an ISO, into out/
bsdtar -xf package.rpmthe files inside an .rpm
bsdtar -caf backup.tar.zst ~/notescreate, compression from the name
bsdtar -cf - folder | ssh pi 'bsdtar -xf - -C /tmp'copy a tree over ssh

Options

-t
list the contents
-x
extract
-c
create
-f FILE
the archive (- for stdin or stdout)
-C DIR
change into DIR first
-a
with -c: compression from the suffix (.gz .xz .zst .zip ...)
-v
name each file
-z / -j / -J
gzip / bzip2 / xz, when creating without -a

Notes

  • tar on Copal is GNU tar; bsdtar is the one that also opens zip, 7z, ISO and rar.
  • It reads rar, but writes only the formats it lists in its manual: tar, zip, 7z, iso, cpio and others.

See also 7z, zip, xorriso, rpm, dpkg

cdparanoia Rip audio CDs to WAV files, correcting for scratches and drive errors.

Discs · command-line tool · cdparanoia 10.2 · stage 12 · The application catalogue · man cdparanoia(1) · home

needs cdparanoia-libs

On Copal: The catalogue's CD ripper: it reads each sector until it is sure, which is what makes a rip from a worn disc sound like the disc.

cdparanoia [options] span [outfile]

Use

With a CD in the drive, rip every track, or chosen ones, to WAV files in the current folder. The progress line shows how hard it had to work.

Examples

cdparanoia -Qthe tracks on the disc
cdparanoia -Bevery track, as track01.cdda.wav...
cdparanoia 3 song.wavtrack 3 only
cdparanoia -B -d /dev/sr1from another drive

Options

-B
batch: every track, each to its own file
-Q
query the disc and print its table of contents
-d DEV
the drive to use
-X
abort on a skip rather than filling it in
-z
never skip: retry an unreadable sector forever

Notes

  • For MP3, FLAC or Ogg with names and tags, abcde runs cdparanoia and an encoder together.
  • The drive needs the cdrom group.

See also abcde, cdrdao

cdrdao Write CDs in disc-at-once mode: audio CDs, gapless, from a TOC or CUE file.

Discs · command-line tool · cdrdao 1.2.6 · stage 12 · The application catalogue · man cdrdao(1) · home

On Copal: The catalogue's audio CD writer: disc-at-once keeps the gaps between tracks exactly as described, which track-at-once cannot.

cdrdao
{show-toc|toc-info|toc-size|read-toc|read-cd|read-cddb|show-data|read-test|disk-info|discid|msinfo|drive-info|unlock|scanbus|simulate|write|copy|blank}
[--device device] [--source-device device] [--driver driver-id] [--source-driver driver-id]
[--simulate] [--speed writing-speed] [--blank-mode mode] [--datafile file] [--read-raw]
[--read-subchan [--no-mode2-mixed] mode] [--tao-source] [--tao-source-adjust link-blocks]
[--fast-toc] [--buffers buffer-count] [--multi] [--overburn] [--eject] [--swap] [--session]
[--force] [--reload] [--keepimage] [--on-the-fly] [--paranoia-mode mode] [--with-cddb]
[--cddb-servers server-list] [--cddb-timeout timeout] [--cddb-directory directory] [--tmpdir
directory] [--keep] [--save] [-n] [-v verbose-level] toc-file

Use

Describe the disc in a table of contents (a .toc or .cue file) that lists the WAV files, then write it. It can also copy a whole CD.

Examples

cdrdao scanbusthe drives it can see
cdrdao write --device /dev/sr0 disc.tocburn from a TOC
cdrdao write --device /dev/sr0 --speed 8 disc.cueslower, from a CUE
cdrdao read-cd --device /dev/sr0 copy.tocread a whole CD to image + TOC
cdrdao show-toc disc.toccheck a TOC before burning

Options

write TOC
burn the disc described in TOC
read-cd TOC
read a CD into an image and a TOC
show-toc TOC
print what a TOC describes
scanbus
list drives
--device DEV
the drive (/dev/sr0)
--speed N
the writing speed
--eject
eject when done

Notes

  • A TOC file is plain text: one TRACK AUDIO block per track, each with FILE "track01.wav" 0.
  • Access to the drive is the cdrom group's.

See also cdparanoia, abcde, xorriso

cdw A terminal front end for burning CDs and DVDs: data discs, ISO images, erasing.

Discs · terminal program · cdw 0.8.1 · stage 12 · The application catalogue · man cdw(1) · home

needs cdrkit, libburn, libcdio, libformw, libintl, libmenuw, libncursesw, libpanelw

On Copal: The catalogue's disc burner for a machine with no desktop, driving the command-line burning tools through menus.

cdw [--help] [--version] [--enable-dvd-rp-dl] [--escdelay=X]

Use

Start it with a burner attached; pick files or an ISO image from the menus, and write them. It calls the underlying tools (xorriso and others) and shows what they report.

Examples

cdwthe menus
lsblk -o NAME,TYPE,MODEL | grep romis there a drive (sr0)?
F1 ? (in cdw) help: the keys of the current window
Enter choose
Q quit

Options

Notes

  • Writing needs access to the drive, /dev/sr0, which the group cdrom owns: doas adduser $USER cdrom, then log in again.
  • Its settings, including which drive and which tools, are in its configuration window and ~/.cdw/cdw.conf.

See also xorriso, cdrdao, cdparanoia

dpkg Look inside Debian and Ubuntu packages: list, inspect and unpack .deb files.

Discs · command-line tool · dpkg 1.23.7 · stage 12 · The application catalogue · man dpkg(1) · home

needs tar, xz, libbz2, libmd, zlib

On Copal: The catalogue's way to open a .deb on Alpine, to see what it holds or take files out of it. Not for installing: Alpine's packages are apk's.

dpkg [option...] command

Use

dpkg-deb does the looking: -c lists the files, -I shows the package's information, -x extracts the files into a folder.

Examples

dpkg-deb -I package.debname, version, dependencies, description
dpkg-deb -c package.debthe files it contains
dpkg-deb -x package.deb out/extract the files into out/
dpkg-deb -e package.deb ctl/its control files and install scripts
dpkg -c package.debthe same as dpkg-deb -c

Options

-c, --contents
list the contents (as dpkg-deb -c)
-I, --info
show the package information
-x DIR
extract the files into DIR (with dpkg-deb)
-e DIR
extract the control files (with dpkg-deb)

Notes

  • dpkg -i would install into a Debian database that nothing here reads: do not. The program inside is built for glibc and will not run on musl as it is.
  • bsdtar -xf package.deb shows the layers: control.tar.* and data.tar.*, the second holding the files.

See also rpm, bsdtar, apk

mksquashfs Pack a folder into a SquashFS image -- compressed, read-only, mountable -- and unsquashfs to unpack one.

Discs · command-line tool · squashfs-tools 4.7.5 · stage 12 · The application catalogue · man mksquashfs(1) · home

needs lz4-libs, xz-libs, lzo, zlib, zstd-libs

On Copal: The catalogue's SquashFS tools: the format of live systems and of Alpine's own boot images, and a way to keep a large folder compressed yet browsable.

mksquashfs source1 source2 ...  FILESYSTEM [OPTIONS] [-e list of exclude dirs/files]

Use

mksquashfs FOLDER IMAGE writes a compressed image of the folder. Mount it read-only to use the files in place, or unsquashfs to get them back.

Examples

mksquashfs ~/photos photos.sqfs -comp zstdan image, zstd-compressed
unsquashfs -l photos.sqfslist what is inside
unsquashfs -d restored photos.sqfsunpack into restored/
doas mount -o loop,ro photos.sqfs /mntbrowse it in place

Options

-comp ALG
compression: gzip, xz, lz4, zstd, lzo
-b SIZE
block size (larger compresses better)
-e NAMES
exclude these files
-noappend
overwrite the image rather than add to it
-processors N
threads to use

Notes

  • Without -noappend, a second run adds to an existing image rather than replacing it.
  • The image is read-only by design; to change it, unpack, edit, and pack again.

See also bsdtar, xorriso

rpm Look inside Red Hat, Fedora and SUSE packages: list, inspect and unpack .rpm files.

Discs · command-line tool · rpm 4.19.1.1 · stage 12 · The application catalogue · man rpm(8) · home

needs rpm-scripts, acl-libs, libarchive, libbz2, libcap2, libcrypto3, libdw, libelf

On Copal: The catalogue's way to open a .rpm on Alpine -- to read what a package holds, or take one file out of it. Not for installing: Alpine's packages are apk's.

QUERYING AND VERIFYING PACKAGES:
    rpm {-q|--query} [select-options] [query-options]

    rpm --querytags

    rpm {-V|--verify} [select-options] [verify-options]

INSTALLING, UPGRADING, AND REMOVING PACKAGES:
    rpm {-i|--install} [install-options] PACKAGE_FILE ...

    rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

    rpm {-F|--freshen} [install-options] PACKAGE_FILE ...

...

Use

Query a package file with -qp and a second letter for what to show. To unpack it, turn it into a cpio stream with rpm2cpio.

Examples

rpm -qpi package.rpmname, version, description
rpm -qpl package.rpmthe files it contains
rpm -qp --scripts package.rpmwhat it would run on install
rpm2cpio package.rpm | cpio -idmvunpack it into this folder
bsdtar -xf package.rpmthe same, in one step

Options

-q, --query
query mode
-p, --package
query a package file (not an installed package)
-l, --list
list its files
-i
with -q: its information
--scripts
with -q: its install scripts

Notes

  • rpm -i would try to install into an rpm database Alpine does not use: do not. A program packaged only as .rpm needs rebuilding for Alpine, or a Flatpak.
  • A .rpm is built for glibc; its binaries will not run on musl as they are.

See also dpkg, bsdtar, apk

unarj List, test and extract .arj archives -- the DOS-era format.

Discs · command-line tool · unarj 2.65 · stage 12 · The application catalogue · home

On Copal: The catalogue's key to old archives: software and files from the 1990s, BBS downloads and old disk images often arrive as .arj.

Use

A command letter, then the archive. It only reads: it cannot make .arj files.

Examples

unarj l old.arjlist the contents
unarj t old.arjtest it for damage
unarj x old.arjextract, keeping folders
unarj e old.arjextract everything into this folder

Options

l ARCHIVE
list
t ARCHIVE
test
x ARCHIVE
extract with paths
e ARCHIVE
extract without paths

Notes

  • It is the free demonstration version: it reads ordinary archives but not multi-volume or password-protected ones. 7z x old.arj handles more.
  • Names from DOS come in capitals and 8.3 form, as they were stored.

See also 7z, bsdtar, zip

xorriso Make ISO 9660 images and burn them: data discs, bootable images, and updates to both.

Discs · command-line tool · xorriso 1.5.8 · stage 12 · The application catalogue · man xorriso(1) · home

needs libisoburn

On Copal: The catalogue's ISO tool, and the one that makes bootable images: its -as mkisofs mode takes the options of the classic mkisofs.

xorriso [settings|actions]

Use

Build an image from a folder, burn an image to a disc, or list and extract what an image holds. -as mkisofs and -as cdrecord accept the older tools' options, which is what most recipes online use.

Examples

xorriso -as mkisofs -o backup.iso -J -R ~/Documentsan ISO from a folder
xorriso -indev image.iso -ls /what is in an image
xorriso -osirrox on -indev image.iso -extract / out/unpack it
xorriso -as cdrecord -v dev=/dev/sr0 image.isoburn it to a disc
xorriso -devicesthe burners it sees

Options

-as mkisofs
behave like mkisofs (-o OUT, -J, -R, -V LABEL)
-as cdrecord
behave like cdrecord (dev=, -v, blank=)
-indev FILE
read an existing image or disc
-outdev FILE
write to an image or disc
-ls PATH
list a folder inside the image
-extract A B
copy A from the image to B (with -osirrox on)
-devices
list optical drives

Notes

  • -J -R add Joliet and Rock Ridge: long names for Windows and Unix. Without them names are cut to 8.3 capitals.
  • Burning needs the cdrom group, which owns /dev/sr0.

See also cdw, cdrdao, bsdtar

zip Make .zip archives -- and, with unzip, list and extract them.

Discs · command-line tool · zip 3.0 · stage 12 · The application catalogue · man zip(1) · home

needs unzip

On Copal: The catalogue's zip pair: the archive format every other system opens without asking, for sending folders to Windows and Mac users.

zip [-aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$] [--longoption ...] [-b path] [-n suffixes] [-t date]
[-tt date] [zipfile [file ...]] [-xi list]

zipcloak (see separate man page)

zipnote (see separate man page)

zipsplit (see separate man page)

Note:  Command line processing in zip has been changed to support long options and handle all
options and arguments more consistently.  Some old command lines that depend on command line
inconsistencies may no longer work.

Use

zip ARCHIVE FILES adds files to an archive, creating it if needed; -r takes whole folders. unzip extracts, unzip -l lists.

Examples

zip -r photos.zip ~/Pictures/tripa folder, recursively
zip notes.zip *.txtsome files
zip -e secret.zip plan.txtwith a password
unzip -l photos.zipwhat is inside
unzip photos.zip -d ~/restoreextract into a folder

Options

-r
include folders, recursively
-e
encrypt, asking for a password
-9
best compression (-1 fastest)
-u
update: add only changed files
-x PATTERN
leave matching files out
-q
quiet

Notes

  • zip's own password encryption is weak. For real secrecy use 7z a -p -mhe=on, which is AES-256 and hides the file names too.
  • zip -r stores paths as given: zip -r a.zip /home/you/x stores the full path, so change into the folder first for short ones.

See also unzip, 7z, bsdtar

Disks

lsblk List the disks and partitions, as a tree, with sizes and mount points.

Disks · lsblk 2.42.3 · stage 5 · Compressed swap in RAM (zram) · man lsblk(8) · home

needs libblkid, libmount, libncursesw, libsmartcols

On Copal: The answer to "which device is the card" before anything that writes to one -- sfdisk, dd, mkfs. Stage 5 installs util-linux, which brings it; BusyBox has no lsblk.

lsblk [options] [device...]

Use

Show every block device: whole disks, their partitions beneath them, and where each is mounted. Run it before and after plugging something in and the new line is the new device.

Examples

lsblkthe tree: disks, partitions, mounts
doas lsblk -ffilesystems: type, label, UUID, free space
lsblk -o NAME,SIZE,TYPE,TRAN,MODELwith the bus (usb, sata...) and model
lsblk -pfull paths, /dev/sda1 not sda1
lsblk -dthe disks only, no partitions
lsblk -J /dev/sdaone disk, as JSON for a script

Options

-f, --fs
filesystem type, label, UUID, available space, use
-o, --output LIST
choose the columns; -H lists them all
-p, --paths
full device paths
-d, --nodeps
whole disks only
-l, --list
a flat list instead of the tree
-J, --json
JSON output
-b, --bytes
sizes in bytes

Notes

  • The names say the bus: mmcblk0 is an SD card (partitions mmcblk0p1), sda a USB or SATA disk (sda1), nvme0n1 an NVMe drive (nvme0n1p1), vda a virtual machine's disk. A Pi booting from USB has its root on sda, not mmcblk0.
  • -f without root shows blank FSTYPE and UUID columns: reading them means reading the device. Use doas lsblk -f.
  • zram0 with [SWAP] is Copal's compressed swap in RAM (stage 5), not a disk.

See also sfdisk, resize2fs, zramctl, dmesg

resize2fs Grow or shrink an ext4 filesystem to fit its partition.

Disks · e2fsprogs-extra 1.47.4 · stage 2 · Format p2 and move the apk cache · man resize2fs(8) · home

needs e2fsprogs, libblkid, libcom_err, e2fsprogs-libs, libuuid

On Copal: The second half of stage 8: after sfdisk makes the root partition fill the disk, resize2fs makes the filesystem fill the partition -- while it is mounted as /.

resize2fs [ -fFpPMbs ] [ -d debug-flags ] [ -S RAID-stride ] [ -z undo_file ] device [ size ]

Use

Given only a device, grow its ext2/3/4 filesystem to the size of the partition. Growing works while mounted; shrinking needs the filesystem unmounted and checked first.

Examples

doas resize2fs /dev/sda2grow to fill the partition (mounted is fine)
doas resize2fs -P /dev/sdb2the smallest it could shrink to
doas e2fsck -f /dev/sdb2before a shrink: check, unmounted
doas resize2fs /dev/sdb2 20Gthen shrink to 20 GiB
df -h /the new size, as the system sees it

Options

SIZE
the new size: 20G, 500M; none means the partition's size
-P
print the minimum size and change nothing
-M
shrink to that minimum
-p
show progress
-f
force: skip the safety checks

Notes

  • Order matters. To grow: partition first (sfdisk), then resize2fs. To shrink: resize2fs first, then the partition -- the other way round cuts the end off the filesystem.
  • "Please run 'e2fsck -f' first" before a shrink is not optional: it needs a clean check since the last mount. That means from another system, or another card, for the root.
  • ext4 only. The FAT boot partition (p1) is not resized by this.

See also sfdisk, lsblk

sfdisk Read, save, restore and change a disk's partition table, from a script.

Disks · sfdisk 2.42.3 · stage 8 · Grow p2 into the free space · man sfdisk(8) · home

needs libfdisk, libncursesw, libsmartcols

On Copal: Stage 8 grows the root partition into the rest of the disk with it, while that partition is mounted -- which parted refuses to do. The same one line claims the space after a VM's disk is enlarged.

sfdisk [options] device [-N partition-number]

sfdisk [options] command

Use

Print a partition table, dump it to a file you can restore, or rewrite it from lines of input. It never prompts, which is what makes it the tool for a script -- and the one to run with -n first.

Examples

doas sfdisk -l /dev/sdathe partitions, in sectors and sizes
doas sfdisk -F /dev/sdaunpartitioned space
doas sfdisk -d /dev/sda > sda.dumpsave the table as text
doas sfdisk /dev/sda < sda.dumpput it back
echo ', +' | doas sfdisk -n -N 2 /dev/sdadry run: grow partition 2 to the end
echo ', +' | doas sfdisk --no-reread -N 2 /dev/sdado it, mounted (stage 8's line)
doas partx -u /dev/sdatell the kernel the new size

Options

-l, --list
list the partitions
-F, --list-free
list the free areas
-d, --dump
the table as sfdisk input, to save
-N, --partno N
change partition N only
-n, --no-act
do everything but write
--no-reread
do not refuse because the disk is in use
-X, --label TYPE
create a new table: dos or gpt
--delete DEV [N]
delete partitions
-q, --quiet
fewer messages

Notes

  • ', +' means: keep the start, make it as large as possible. Changing the table does not change the filesystem inside: grow that with resize2fs afterwards.
  • On a disk in use -- the one you booted from -- sfdisk refuses unless given --no-reread, and the kernel keeps the old sizes until told: partx -u DISK, as stage 8 does, or a reboot. That refusal is about the kernel's copy of the table, not a danger to the data.
  • Keep a dump before any change. A table restored from sfdisk -d output gives back every partition, data included, as long as nothing has been formatted in the meantime.

See also lsblk, resize2fs

zramctl Show and set up zram devices: compressed swap in RAM.

Disks · util-linux-misc 2.42.3 · stage 5 · Compressed swap in RAM (zram) · man zramctl(8) · home

needs setarch, libblkid, libfdisk, libmount, libncursesw, libsmartcols, utmps-libs, libuuid

On Copal: Stage 5 gives every Copal machine a zram swap half the size of RAM, compressed with lz4 -- on a 512 MB board the largest single win, and it spares the card the writes of disk swap.

Get info:
    zramctl [options]

Reset zram:
    zramctl -r zramdev...

Print name of first unused zram device:
    zramctl -f

Set up a zram device:
    zramctl [-f | zramdev] [-s size] [-t number] [-a algorithm]

Use

With no arguments, show each zram device: its size, how much is stored in it and how small that compressed to. Copal sets zram up at boot from /etc/local.d/zram.start; zramctl is for looking, or for changing it.

Examples

zramctlsize, data stored, compressed size
free -mswap in use, zram included
cat /proc/swapszram0 at priority 100, before any disk swap
doas swapoff /dev/zram0stop using it (to resize)...
doas zramctl -r /dev/zram0...reset it...
doas zramctl -a lz4 -s 1G /dev/zram0 # ...set it up again at 1 GiB
doas mkswap /dev/zram0 && doas swapon -p 100 /dev/zram0...and swap on it

Options

-s, --size SIZE
the device size: 512M, 1G
-a, --algorithm ALG
lzo, lz4, lz4hc, deflate, 842 or zstd
-r, --reset DEVICE
empty and release a device
-f, --find
the first free device
-o, --output LIST
choose the columns
-b, --bytes
sizes in bytes

Notes

  • DISKSIZE is the most it will take, not memory spent: RAM is used only for what is stored, compressed. DATA against COMPR is the ratio -- usually 2 to 3 times.
  • A change made with zramctl is gone at the next boot. To change the size for good, edit the disksize line in /etc/local.d/zram.start.
  • zram is swap, not more memory: a machine that swaps constantly is slow either way. Its gain is that a burst -- a big build, a browser -- no longer ends in the out-of-memory killer.

See also lsblk, dmesg

Documents

pdftotext Pull the text out of a PDF -- and, with the other poppler tools, split, join and inspect PDFs.

Documents · command-line tool · poppler-utils 25.12.0 · stage 12 · The application catalogue · man pdftotext(1) · home

needs cairo, freetype, libintl, lcms2, poppler

On Copal: The catalogue's PDF toolkit (poppler-utils): search a PDF with grep, read one over SSH, or feed it to a script. Its siblings pdfinfo, pdfunite, pdfseparate and pdftoppm come in the same package.

pdftotext [options] PDF-file [text-file]

Use

pdftotext FILE.pdf writes FILE.txt; with - as the output it prints to the terminal. -layout keeps columns and tables where they were, instead of reflowing the text.

Examples

pdftotext paper.pdfpaper.txt beside it
pdftotext -layout invoice.pdf -to the terminal, columns kept
pdftotext -f 3 -l 5 book.pdf part.txtpages 3 to 5 only
pdftotext paper.pdf - | grep -i copalsearch inside a PDF
pdfinfo paper.pdfpages, size, author, producer
pdfunite a.pdf b.pdf both.pdfjoin
pdfseparate book.pdf page-%d.pdfone file per page
pdftoppm -png -r 150 paper.pdf pagepages as PNG pictures

Options

-layout
keep the physical layout: columns, tables
-f N
-l N the first and last page
-raw
the text in the order it is stored
-enc UTF-8
the output encoding
-nopgbrk
no form feed between pages
-
as the output file: stdout

Notes

  • A scanned PDF is pictures of pages and has no text to extract: the output is empty. Run the pages through tesseract (from pdftoppm's images) to get text.
  • Multi-column papers come out interleaved without -layout, and hyphenated at line ends either way.

See also qpdf, tesseract

qpdf Rewrite PDFs without changing their content: split, merge, rotate, decrypt, repair.

Documents · command-line tool · qpdf 12.3.2 · stage 12 · The application catalogue · man qpdf(1) · home

needs qpdf-libs

On Copal: The catalogue's PDF surgeon. It works on the PDF's structure, not its pictures, so nothing is re-rendered or lost -- and it repairs files other programs refuse to open.

qpdf [ options ] infilename [ outfilename ]

Use

Read one PDF and write another, with pages chosen, rotated or merged on the way. --empty --pages builds a new file from pages of others; --check reports what is wrong with a damaged one.

Examples

qpdf --empty --pages a.pdf b.pdf -- both.pdfmerge
qpdf in.pdf --pages . 1-3 -- first3.pdfthe first three pages
qpdf in.pdf --pages . z-1 -- reversed.pdfevery page, backwards
qpdf --split-pages in.pdf out-%d.pdfone file per page
qpdf in.pdf --rotate=+90:2 out.pdfrotate page 2
qpdf --decrypt --password=secret locked.pdf open.pdfremove a password you know
qpdf --check broken.pdfwhat is wrong with it
qpdf broken.pdf fixed.pdfrewriting often repairs it

Options

--empty
start from an empty PDF (with --pages)
--pages F R ... --
pages R of file F, in order; . is the input file
--split-pages
write each page (or group) as its own file
--rotate=[+-]DEG:R
rotate pages R
--decrypt
remove encryption (with --password)
--linearize
optimise for fast web viewing
--check
check the structure and report
--show-npages
the page count

Notes

  • Page ranges: 1-5, 3,7,9, z is the last page, r1 counts from the end, 1-z:odd every odd page.
  • --decrypt needs the password when there is one to open it; for a file that opens freely but forbids printing, no password is asked.
  • It never re-compresses images, so output is the same quality -- and roughly the same size -- as the input.

See also pdftotext

sc-im A spreadsheet in the terminal, with vim's keys: formulas, CSV, and Excel import.

Documents · terminal program · sc-im 0.8.5 · stage 12 · The application catalogue · man sc-im(1) · home

needs libncursesw, libxml2, libzip

On Copal: The catalogue's spreadsheet for a machine with no desktop, or for a quick sum over SSH. It opens CSV and XLSX, and writes both back.

sc-im [OPTION]... [FILE]

Use

Move between cells with vim's keys, type = to enter a number or a formula, < or > for text. :w saves in its own format; CSV and tab-separated files open and export directly.

Examples

sc-ima new sheet
sc-im budget.csvopen a CSV
sc-im report.xlsximport a spreadsheet
sc-im --nocurses --quit_afterload data.csvprint it, no screen
= @sum(B2:B10) (in sc-im) a formula in the current cell
< > a text label, left / right aligned
e E x edit the number / edit the text / clear the cell
:e csv out.csv export as CSV
:w :q save / quit; u undo

Options

--nocurses
no screen: print the sheet and read commands from stdin
--quit_afterload
leave after loading (with --nocurses: a print)
--sheet=SHEET
which sheet of an XLSX to open
--xlsx_readformulas
import formulas from XLSX, not only their values
--output=FILE
where --nocurses writes

Notes

  • Formulas use sc's functions with an @: @sum, @avg, @max, @if. Excel's SUM() spelling is not understood.
  • It exports as well as imports: :e xlsx FILE for a spreadsheet program, :e mkd FILE for a Markdown table, :e txt for plain text.
  • :help is the full manual, inside the program.

See also vim, python3

Editors

hx Helix: a modal editor with selections first, and a language server and syntax trees built in.

Editors · terminal program · helix 25.07.1 · stage 12 · The application catalogue · home

On Copal: The catalogue's modern modal editor: what nvim needs a config for, Helix does out of the box -- completion, go-to-definition, and a menu for every key. Its command is hx.

Use

Modal like vim, but the selection comes first and the action second: w selects a word, then d deletes it. Press Space for a menu of pickers and commands; every menu says what each key does.

Examples

hx main.rsedit
hx --tutorthe tutorial, about half an hour
hx --healthwhich languages have a server and a grammar
hx --health rustone language in detail
hx --vsplit a.c b.ctwo files side by side
i Esc (in hx) insert / back to normal
w x d select a word / select the line / delete the selection
Space f file picker; Space / search the project
g d g r go to definition / references
:w :q write / quit

Options

--tutor
the tutorial
--health [LANG]
check the language servers and grammars
-c, --config FILE
another config file
--vsplit / --hsplit
open the files in splits
-w, --working-dir D
start in directory D
+N
open the first file at line N

Notes

  • Language servers are programs of their own: hx --health shows which are found. Stage 7's clangd, rust-analyzer, gopls and pylsp are.
  • Config is ~/.config/helix/config.toml; themes are one line: theme = "onedark".
  • Vim habits misfire: dw is wd here, and there is no :s -- select, then s to select within, then c to change.

See also nvim, vim, micro

micro A terminal text editor with the keys of a desktop editor: Ctrl-S, Ctrl-C, Ctrl-V, the mouse.

Editors · terminal program · micro 2.0.15 · stage 12 · The application catalogue · man micro(1) · home

On Copal: The catalogue's editor for anyone who does not want modes. Copy and paste reach the desktop clipboard, and the mouse selects text.

micro [OPTION]... [FILE]... [+LINE[:COL]] [+/REGEX]
micro [OPTION]... [FILE[:LINE[:COL]]]...  (only if the `parsecursor` option is enabled)

Use

Open a file and type. Ctrl-S saves, Ctrl-Q quits, Ctrl-Z undoes, and Ctrl-E opens a command prompt for anything else. Syntax colours, multiple cursors and splits come built in.

Examples

micro notes.txtedit
micro +42 main.cat line 42
micro -cleanwith default settings, to rule out the config
micro -plugin install editorconfigadd a plugin
Ctrl-S Ctrl-Q (in micro) save / quit
Ctrl-F Ctrl-N find / next match
Ctrl-Z Ctrl-Y undo / redo
Ctrl-E command prompt: help, set, vsplit, replace...
Alt-G show the key bindings at the foot

Options

+N
open at line N
-clean
ignore the configuration
-config-dir DIR
use another configuration directory
-plugin install P
install a plugin; remove to take it out
-options
list every setting and its default

Notes

  • Settings are in ~/.config/micro/settings.json, keys in bindings.json; Ctrl-E then set tabsize 4 changes and saves one.
  • Copy and paste reach the desktop's clipboard through wl-copy and wl-paste (its clipboard setting is external).
  • Ctrl-E help opens the manual inside the editor.

See also nano, nvim, hx

nano The simplest terminal editor: type, and the keys are listed at the bottom.

Editors · terminal program · nano 9.2 · stage 12 · The application catalogue · man nano(1) · home

needs libncursesw

On Copal: The catalogue's editor for anyone new to the terminal, and the one to reach for to change a config file quickly -- nothing to learn before the first edit.

nano [options] [[+line[,column]] file]...

nano [options] [[+[crCR]{/|?}string] file]...

Use

Open a file and type. The two lines at the foot list the commands: ^ means Ctrl, M- means Alt. Ctrl-O saves ("write Out"), Ctrl-X leaves.

Examples

nano notes.txtedit
doas nano /etc/hostnameedit a system file
nano -l script.shwith line numbers
nano +42 main.cat line 42
nano -/ notes.txtmodern keys: Ctrl-S save, Ctrl-Q quit, Ctrl-C copy
Ctrl-O Ctrl-X (in nano) save / quit
Ctrl-W Ctrl-\ find / find and replace
Ctrl-K Ctrl-U cut the line / paste
Alt-U undo; Ctrl-G help

Options

-l, --linenumbers
show line numbers
-m, --mouse
use the mouse
-i, --autoindent
keep the indentation of the line above
-E, --tabstospaces
type spaces for Tab
-T N, --tabsize=N
tab width
-B, --backup
keep a backup (file~)
-v, --view
read-only
-/, --modernbindings
Ctrl-S, Ctrl-Q, Ctrl-C, Ctrl-V as elsewhere

Notes

  • Settings go in ~/.config/nano/nanorc, one set per line: set linenumbers, set modernbindings.
  • doas nano FILE edits as root. Keep root's edits to system files -- your own files edited as root end up owned by root.

See also micro, vim, nvim

vis A small vi-like editor with multiple selections and sam's structural regular expressions.

Editors · terminal program · vis 0.9 · stage 12 · The application catalogue · man vis(1) · home

needs !outils-vis, lua5.3-lpeg, acl-libs, lua5.3-libs, libncursesw, libtermkey

On Copal: The catalogue's lean modal editor: vi's keys in a fraction of vim's size, plus multiple cursors and sam-style editing for changing many places at once.

vis [-v] [+command] [--] [files ...]

Use

Edit as in vi. What it adds: several selections at once, all edited together, and :x/pattern/ command to select every match in the selection and act on each.

Examples

vis notes.txtedit
i Esc (in vis) insert / normal
Ctrl-N select the word, then the next match, and the next...
I A insert at the start / end of every selection
:x/foo/ c/bar/ change every foo in the selection to bar
:w :q write / quit

Options

-v
the version
--
everything after is a file name

Notes

  • Configuration is Lua: ~/.config/vis/visrc.lua.
  • It is vi, not vim: no :s///. :x/old/ c/new/ over the selection (:, for the whole file) does the same job.

See also vim, nvim, hx

Emulation

qemu-system-x86_64 Emulate a whole 64-bit PC: boot another operating system inside a window on the Pi.

Emulation · command-line tool · qemu-system-x86_64 11.0.3 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs qemu, qemu-edk2-i386-vars, libaio, libbpf, capstone, libdw, libfdt, glib

On Copal: The store's PC emulator, on the 64-bit boards: run an x86 Linux, a BSD or DOS inside Copal. On an ARM board it emulates the CPU in software, so it works everywhere and fast nowhere.

usage: qemu-system-x86_64 [options] [disk_image]
'disk_image' is a raw hard disk image for IDE hard disk 0

Use

Make a disk image with qemu-img, then boot an installer ISO with it attached. -m sets the memory, -smp the CPUs; the display opens in a window.

Examples

qemu-img create -f qcow2 disk.qcow2 20Ga 20 GB disk that grows as used
qemu-system-x86_64 -m 2G -smp 2 -hda disk.qcow2 -cdrom install.iso -boot dinstall
qemu-system-x86_64 -m 2G -smp 2 -hda disk.qcow2boot the installed system
qemu-system-x86_64 -m 1G -nographic -hda disk.qcow2serial console, no window
qemu-system-x86_64 -accel helpthe accelerators this build has

Options

-m SIZE
memory: 1G, 2048M
-smp N
CPUs
-hda FILE
the first disk
-cdrom FILE
an ISO in the CD drive
-boot d
boot from the CD (c for the disk)
-nographic
no window: the console on this terminal
-accel NAME
tcg (software) is what an ARM board has
-bios FILE
firmware: /usr/share/qemu/edk2-x86_64-code.fd for UEFI

Notes

  • On an ARM Pi there is no KVM for x86: every instruction is translated, so a guest runs at a small fraction of native speed. Small, text-mode systems are the good fit.
  • qemu-img comes with it as an optional from 24 Sep 2026; before that, doas apk add qemu-img.
  • 64-bit boards only: its row is gated to aarch64 and x86_64.

See also waydroid, mednafen

waydroid Run Android apps in a container on the desktop, each in its own window or a full Android screen.

Emulation · command-line tool · waydroid 1.6.2 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs dnsmasq, gbinder-python, iptables, kmod, lxc, py3-dbus, py3-gobject3, py3-pyclip

On Copal: The store's Android layer: LineageOS in a container, sharing the Linux kernel, drawn through Wayland -- so it needs the Hyprland desktop, not i3.

usage: waydroid [-h] [-V] [-l LOG] [--details-to-stdout] [-v] [-q]
                {status,log,init,upgrade,session,container,app,prop,show-full-ui,first-launch,shell,logcat,adb,bugreport} ...
options:

Use

Initialise it once (it downloads the Android images, about a gigabyte), start the container service, then start a session from the desktop and open the full UI or single apps.

Examples

doas waydroid initdownload and set up the images, once
doas rc-service waydroid-container startthe container service
waydroid session start &the Android session, in the desktop
waydroid show-full-uithe Android screen in a window
waydroid app install app.apkinstall an APK
waydroid statusis it running, and what

Options

init
set up the images (root)
container
start, stop, restart the container (root)
session start
start the Android session (as you, in the desktop)
show-full-ui
the whole Android screen
app install APK
install an app; app list the installed ones
prop
read and set Android properties

Notes

  • It needs the kernel's binder, which Copal's kernel has built in, and a Wayland session: from i3 or over SSH it cannot draw.
  • To start it at boot: doas rc-update add waydroid-container.
  • Not on ARMv6: its row is gated off there.

See also scrcpy, qemu-system-x86_64

Engineering

admesh Check an STL mesh, and repair it: close holes, fix normals, remove stray facets.

Engineering · command-line tool · admesh 0.98.5 · stage 12 · The application catalogue · man admesh(1) · home

On Copal: The catalogue's STL doctor: a model that a slicer rejects or prints wrong usually has a hole or a flipped face, and admesh reports and fixes both.

admesh [OPTION]... file

Use

Run it on an STL to see its statistics and problems. With options it repairs, scales, rotates or merges, and writes the result with --write-binary-stl or --write-ascii-stl.

Examples

admesh part.stlcheck: size, facets, errors found
admesh -b fixed.stl part.stlrepair everything, write binary STL
admesh --scale=25.4 -b mm.stl inch.stlinches to millimetres
admesh --x-rotate=90 -b up.stl part.stlstand it up

Options

-b, --write-binary-stl=F
write the result as binary STL
-a, --write-ascii-stl=F
write it as ASCII STL
-f, --fill-holes
fill holes in the mesh
-d, --normal-directions
fix facets facing the wrong way
-u, --remove-unconnected
remove facets with no neighbours
-e, --exact
join edges that match exactly
--scale=FACTOR
scale the model
--x-rotate=DEG
rotate about X (also --y-rotate, --z-rotate)
--merge=FILE
add another STL into this one

Notes

  • With no repair options it runs all of them; name one or more to run only those.
  • It reads both ASCII and binary STL; binary output is several times smaller.

See also solvespace-cli

ngspice SPICE circuit simulation: transient, AC and DC analysis of a netlist.

Engineering · command-line tool · ngspice 46 · stage 12 · The application catalogue · man ngspice(1) · home

needs python3, libx11, libxaw, libxt, libgomp, libncursesw, readline

On Copal: The catalogue's circuit simulator, the standard open one: check a filter, an amplifier or a power supply before building it.

ngspice [options] [file ...]

Use

Describe the circuit as a netlist -- components, the nodes they join, their values -- and the analyses to run. Interactively it plots results as ASCII; in batch mode it writes them for another program to plot.

Examples

ngspice rc.cirload it, then 'run' and 'plot v(out)'
ngspice -b rc.cirbatch: run and print, no prompt
ngspice -b -r out.raw rc.cirbatch, results to a rawfile
ngspice -b -o log.txt rc.cirbatch, output to a log
run (at the prompt) run the analyses in the netlist
plot v(out) plot a node's voltage
print v(out) print it as numbers
quit leave

Options

-b, --batch
run and exit
-r, --rawfile FILE
write the results to FILE
-o, --output FILE
write the output to FILE
-i, --interactive
stay interactive even with a file on stdin
-n, --no-spiceinit
ignore .spiceinit files

Notes

  • A netlist's first line is its title and is never read as a component -- a first component there silently disappears.
  • gnuplot out v(out) at the prompt draws the plot with gnuplot, which the catalogue's Science section installs.

See also gnuplot, python3

solvespace-cli SolveSpace from the command line: export and render .slvs models without the window.

Engineering · command-line tool · solvespace 3.2 · stage 12 · The application catalogue · home

needs mesa-gl, atkmm2.28, cairo, fontconfig, freetype, gtk+3.0, gtkmm3, glib

On Copal: The catalogue's scripted CAD: the SolveSpace window designs a part, and this turns it into STL, a drawing or a picture in a Makefile.

Use

Name a command and the .slvs files to apply it to. --output is a pattern: % becomes each input file's name.

Examples

solvespace-cli export-mesh --output %.stl part.slvsa mesh for a slicer
solvespace-cli export-view --view top --output %-top.svg part.slvsa 2D drawing
solvespace-cli thumbnail --output %.png --size 400x400 --view isometric part.slvs
solvespace-cli regenerate part.slvsreload imports, regenerate, save

Options

export-mesh
a triangle mesh (STL, OBJ...)
export-view
a 2D view (SVG, DXF, PDF...), --view VIEW
export-surfaces
exact surfaces (STEP)
thumbnail
a rendered picture, --size WxH
regenerate
reload, regenerate and save
-o, --output PAT
the output name: % is the input's name
-v, --view DIR
top, bottom, left, right, front, back, isometric
-t, --chord-tol N
how finely curves become straight segments

Notes

  • The output format follows the extension of --output: .stl or .obj for a mesh, .svg, .dxf or .pdf for a view.
  • --chord-tol is in millimetres for exports: smaller is smoother and larger.

See also admesh, solvespace

Files

fdupes Find duplicate files -- identical contents, whatever their names -- and optionally delete them.

Files · command-line tool · fdupes 2.4.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man fdupes(1) · home

needs libncursesw, libpcre2-32, sqlite-libs

On Copal: The store's duplicate finder: photos copied twice, downloads saved again, backups of backups. It compares sizes, then checksums, then bytes, so a match is exact.

fdupes [ options ] DIRECTORY ...

Use

Point it at folders; it prints each set of identical files together. Look at the list before deleting anything; -d then asks, set by set, which copy to keep.

Examples

fdupes -r ~/Picturessets of duplicates, recursively
fdupes -rS ~/Downloadswith each file's size
fdupes -rm ~/Musicjust a summary: how many, how much space
fdupes -rd ~/Pictureschoose, set by set, which to keep

Options

-r, --recurse
go into subfolders
-S, --size
show sizes
-m, --summarize
only the totals
-n, --noempty
ignore empty files
-d, --delete
ask which file of each set to keep, delete the rest
-N, --noprompt
with -d: keep the first of each set without asking
-f, --omitfirst
list all but the first file of each set

Notes

  • -dN deletes without asking, keeping whichever file happened to be listed first: check the list without -d first.
  • Deleting is permanent; there is no bin. For a gentler clean-up, rdfind -makehardlinks true keeps every name and frees the space.

See also jdupes, rdfind

jdupes A faster fdupes: find duplicate files, and delete, hard-link or deduplicate them.

Files · command-line tool · jdupes 1.31.1 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man jdupes(1) · home

needs libjodycode, libxxhash

On Copal: The store's fast duplicate finder: the same results as fdupes, much quicker on large folders, and able to replace copies with hard links instead of deleting.

jdupes [ options ] DIRECTORIES ...

Use

The same way as fdupes: point it at folders, read the sets, then decide. Beyond deleting, -L replaces duplicates with hard links, so every name stays and the space is freed.

Examples

jdupes -r ~/Picturessets of duplicates
jdupes -rm ~/Musica summary
jdupes -rL ~/Photoshard-link duplicates together
jdupes -rd ~/Downloadschoose which to keep, set by set

Options

-r, --recurse
go into subfolders
-S, --size
show sizes
-m, --summarize
only the totals
-d, --delete
ask which to keep, delete the rest
-N, --no-prompt
with -d: keep the first without asking
-L, --link-hard
replace duplicates with hard links
-B, --dedupe
copy-on-write deduplication (Btrfs, XFS)
-Q, --quick
skip the final byte-by-byte check (faster, less sure)

Notes

  • Hard links only work within one filesystem, and after linking, editing one name edits them all -- fine for photos, wrong for files you mean to change separately.
  • -Q trades certainty for speed; leave it off before deleting.
  • It comes from Alpine's testing repository (jdupes@testing).

See also fdupes, rdfind

mc Midnight Commander: a two-panel file manager for the terminal, with a viewer and an editor.

Files · terminal program · mc 4.8.33 · stage 4 · X.Org, i3, a terminal and a browser · man mc(1) · home

needs e2fsprogs-libs, glib, gpm-libs, libintl, slang, libssh2

On Copal: The catalogue's terminal file manager, and the first one Copal's menus open for files when there is no desktop. Its skin follows Copal's theme.

mc [-abcCdfhPstuUVx] [-l log] [dir1 [dir2]] [-e [file] ...] [-v file]

Use

Two panels, a folder in each. Select files on one side and copy or move them to the other with a function key; the keys are listed along the bottom. The command line under the panels still works as a shell.

Examples

mcthe two panels
mc ~/Downloads /media/usbopen these two folders
mcedit notes.txtits editor on its own
mcview big.logits viewer on its own
Tab (in mc) switch panels
Insert select a file
F5 F6 F8 copy / move / delete the selection
F3 F4 view / edit
F10 quit

Options

-b
monochrome
-d
no mouse
-u
no subshell (a faster start)
-e FILE
edit FILE, as mcedit
-v FILE
view FILE, as mcview

Notes

  • A function key the terminal keeps for itself has an Esc equivalent: Esc then 0 is F10, Esc then 5 is F5.
  • Ctrl-O hides the panels to show the shell underneath, and brings them back.
  • Settings are in ~/.config/mc/ini; Copal writes only its skin= line.

See also nnn, ranger, rsync

nnn A tiny, fast terminal file manager, driven from the keyboard.

Files · terminal program · nnn 5.2 · stage 12 · The application catalogue · man nnn(1) · home

needs libncursesw, readline

On Copal: The catalogue's lightest file manager: it starts at once even on a Pi Zero, and stays out of the way.

nnn [-aAcCdDeEfgHJKnQrRSuUVxz0h] [-b key] [-F val] [-l val] [-p file] [-P key] [-s name]
    [-t secs] [-T key] [PATH]

Use

Move through folders with the arrows or h j k l, and open a file with Enter. Space selects; the selection can then be copied or moved into the folder you are in.

Examples

nnnthe current folder
nnn ~/Musica folder
nnn -dwith details: size, date, permissions
nnn -Hshow hidden files
h j k l (in nnn) back / down / up / open
Space select; a select all
p v copy / move the selection here
/ filter by name
? every key; q quit

Options

-d
detail mode
-H
show hidden files
-e
open text files in $EDITOR, in the terminal
-o
open files only on Enter

Notes

  • It opens files with xdg-open; without a desktop, -e keeps text files in $EDITOR.
  • Quitting does not change the shell's folder: that takes the small quitcd shell function from nnn's documentation.

See also mc, ranger

ranger A terminal file manager in columns, with previews and vi keys.

Files · terminal program · ranger 1.9.4 · stage 12 · The application catalogue · man ranger(1) · home

needs python3

On Copal: The catalogue's file manager with the most on screen: the parent folder, the current one and a preview side by side.

ranger [--version] [--help] [--debug] [--clean] [--cachedir=directory] [--confdir=directory]
[--datadir=directory] [--copy-config=which] [--choosefile=target] [--choosefiles=target]
[--choosedir=target] [--selectfile=filepath] [--show-only-dirs] [--list-unused-keys]
[--list-tagged-files=tag] [--profile] [--cmd=command] [path ...]

Use

Three columns: the parent folder, the current one, and a preview of what is selected. h and l move out and in; Enter opens. Commands start with :, as in vim.

Examples

rangerthe current folder
ranger ~/Documentsa folder
ranger --copy-config=allwrite its config files, to edit
h j k l (in ranger) out / down / up / in
Space mark a file
yy pp copy / paste
zh show hidden files
q quit

Options

--copy-config=WHICH
copy the default config into ~/.config/ranger
--choosefile=FILE
pick a file, and write its path to FILE
--cmd=CMD
run a ranger command at start

Notes

  • Text previews work out of the box; previews of images and PDFs need helper programs.
  • S opens a shell in the current folder; exit returns to ranger.

See also mc, nnn

rdfind Find redundant files across folders, ranked by which copy is the original, and act on them.

Files · command-line tool · rdfind 1.8.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man rdfind(1) · home

needs nettle, libxxhash

On Copal: The store's duplicate finder for "which copy do I keep?": it ranks files by the order the folders were given, so the first folder's copies win -- right for clearing a backup against the originals.

rdfind [ options ] directory1 | file1 [ directory2 | file2 ] ...

Use

Name the folders, the one to keep first. By default it only writes a report, results.txt; options replace the later copies with links, or delete them. Try with -dryrun true before changing anything.

Examples

rdfind ~/Pictures /media/usb/old-backupreport only: results.txt
rdfind -dryrun true -deleteduplicates true ~/Pictures /media/usb/oldwhat it would delete
rdfind -deleteduplicates true ~/Pictures /media/usb/olddelete the backup's copies
rdfind -makehardlinks true ~/Musiclink duplicates, keep every name

Options

-dryrun true
say what would change, change nothing
-deleteduplicates true
delete all but the highest-ranked copy
-makehardlinks true
replace duplicates with hard links
-makesymlinks true
replace them with symbolic links
-makeresultsfile false
no results.txt
-ignoreempty true
skip empty files (the default)

Notes

  • The order of the folders is the ranking: the first folder's copy is the one kept. Put the originals first.
  • Options take true or false after them, unlike most commands.

See also fdupes, jdupes

Games

adventure Colossal Cave Adventure: the first text adventure, from 1977.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man adventure(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games (bsd-games): the ancestor of Zork and of every text adventure since, typed a command at a time.

Use

Read the description, type a command of one or two words -- go north, get lamp, open grate -- and read what happens. Map the cave on paper as you go; that is how it was meant to be played.

Examples

adventurestart (answer "no" to the instructions, or read them)
enter building (in the cave) move, by direction or by place
get lamp take things; inventory what you carry
look describe the place again
save stop here, to continue later
quit end the game, with a score

Options

Notes

  • The first thing to do is take the lamp. The cave is dark.
  • It understands the first five letters of a word: inven is inventory.
  • help and info are commands too: the game explains itself.

See also frotz, nethack

angband Angband: a hundred-level descent to Morgoth, in the lineage of Moria.

Games · terminal program · angband 4.2.5 · stage 12 · The application catalogue · home

needs sdl2, sdl2_image, sdl2_mixer, sdl2_ttf, libncursesw

On Copal: The catalogue's long-form roguelike: a character built over many hours, a town to return to, and the dungeon from Tolkien's Moria onward.

Use

Create a character, buy supplies in the town, and descend. Levels are made afresh every time you take the stairs, so going back up and down is normal. ? is the help, Enter a menu of every command.

Examples

angbandcontinue, or make a character
angband -na new character
angband -lthe savefiles there are
angband -uGandalfplay the savefile named Gandalf
arrows / hjkl (in angband) move
Enter the menu of every command
g i w pick up / inventory / wield
< > stairs up / down
Ctrl-X save and quit

Options

-n
a new character (overwrites the default savefile, without -u)
-u NAME
use the savefile NAME
-l
list the savefiles
-c
choose a savefile from a menu
-w
bring a dead character back (marks the save)

Notes

  • Your saves and settings are in ~/.angband, not in /usr/share.
  • -n without -u replaces the default character. Name a new one: angband -n -uSomeone.
  • It comes from Alpine's testing repository (angband@testing).

See also zangband, nethack, brogue

asciiquarium An aquarium in the terminal: fish, sharks, a castle and bubbles, animated.

Games · terminal program · asciiquarium 1.1 · stage 12 · The application catalogue · home

needs perl, perl-term-animation

On Copal: One of the catalogue's toys: something alive in a spare terminal or a tmux pane, and a quick test of a terminal's colours and speed.

Use

Run it, watch, press q to leave. It fills the terminal at whatever size it is, and redraws when the window changes.

Examples

asciiquariumwatch
q (while running) quit
p pause
r redraw

Options

Notes

  • It is a Perl program: the first frame takes a moment on a Pi.
  • It ignores --help and simply starts.

See also cmatrix, cbonsai

atc Air Traffic Control: route planes through your airspace without a collision.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man atc(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games, and the best of them -- unplayable until you have read man atc, and excellent afterwards.

atc [-u?lstp] [-gf game name] [-r random seed]

Use

Planes enter at the edges; guide each to its exit or airport at the right altitude, and keep them apart. Every command starts with the plane's letter, then the action and its value, and Enter sends it; ? lists what may come next at any point.

Examples

atcthe default airspace
atc -lthe airspaces there are
atc Killera harder one
atc -sthe scores
man atcread this first

Options

-l
list the scenarios
-s
print the score table
SCENARIO
play that airspace: Default, Atlantis, Killer, OHare

Notes

  • ba5 sends plane b to 5000 feet; btd turns it to heading east. Directions are the eight keys around s: w north, e north-east, d east, round to q north-west.
  • Planes enter at 7000 feet and must leave through their exit at 9000, or land at their airport by going to 0 directly over it.

See also robots, snake

brogue Brogue: a roguelike made to be learned -- twenty-six levels, no classes, beautiful in a terminal.

Games · terminal program · brogue 1.15.1 · stage 12 · The application catalogue · home

needs sdl2, sdl2_image

On Copal: The catalogue's most approachable roguelike: fewer keys than NetHack, a mouse that works, and a dungeon that shows you what it is doing.

Use

Descend twenty-six levels to the Amulet of Yendor and back out. You build your character from what you find, not from a class. The mouse moves you and describes what you point at; ? lists the keys.

Examples

broguethe menu
brogue -na new game at once
brogue -s 12345a game from a seed (share it)
brogue --scoresthe high scores
brogue -v game.broguerecwatch a recording
arrows / hjkl (in brogue) move; x explore automatically
i s inventory / search; > descend
? every key; Q quit

Options

-n
a new game, skip the menu
-s SEED
a new game from SEED
-o FILE
open a saved game
-v FILE
view a recording
--scores
print the scores
--size N
font size, 1 to 20 (in a window build)

Notes

  • x explores the level for you until something interesting happens; most of the game is choosing when to stop.
  • Every game is recorded; recordings, saves and scores are kept in ~/.local/share/brogue.

See also nethack, angband

cbonsai Grow a bonsai tree in the terminal, slowly, or print one.

Games · command-line tool · cbonsai 1.4.2 · stage 12 · The application catalogue · man cbonsai(6) · home

needs libncursesw, libpanelw

On Copal: One of the catalogue's toys: a different tree every time, as a screensaver or as the first thing a new shell prints.

cbonsai [OPTION]...

Use

With no options it draws a finished tree. -l shows it growing; -S is the screensaver, growing tree after tree until a key is pressed.

Examples

cbonsaia tree, finished
cbonsai -lwatch it grow
cbonsai -Sscreensaver: one tree after another
cbonsai -p -m "$(fortune -s)"print a tree with a saying beside it

Options

-l, --live
show each step of growth
-t, --time=SECS
the delay between steps with -l
-i, --infinite
keep growing trees
-S, --screensaver
-l and -i together, quit on any key
-m, --message=STR
a message beside the tree
-p, --print
print the tree and leave it on the terminal
-L, --life=N
how big it grows (default 32)

Notes

  • -p makes it usable in a shell's start-up: the tree stays on screen above the prompt.

See also asciiquarium, cmatrix, fortune

cmatrix The falling green characters of The Matrix, in the terminal.

Games · terminal program · cmatrix 2.0 · stage 12 · The application catalogue · man cmatrix(1) · home

needs libncursesw

On Copal: One of the catalogue's toys, and a screensaver for a console with nothing else to show.

cmatrix [-abBflohnsmVx] [-u update] [-C color]

Use

Run it and watch; q quits. Keys change it while it runs: speed, colour, boldness.

Examples

cmatrixwatch
cmatrix -sscreensaver: any key ends it
cmatrix -b -C bluebold, in blue
cmatrix -u 2faster (0 fastest, 9 slowest)
cmatrix -asmooth, asynchronous columns
0-9 (while running) speed
! @ # $ % ^ & ) red, green, yellow, blue, magenta, cyan, white, ...
q quit

Options

-s
screensaver mode: exit on the first key
-b / -B
some / all characters bold
-C COLOR
green, red, blue, white, yellow, cyan, magenta, black
-u N
the delay, 0 to 9
-a
asynchronous scroll
-l
Linux console mode, with the matrix font
-m
lambda mode: every character is a lambda

Notes

  • -l changes the console font and only makes sense on a text console, not in a terminal window.

See also asciiquarium, cbonsai

figlet Print text in large letters made of characters.

Games · command-line tool · figlet 2.2.5 · stage 12 · The application catalogue · man figlet(6) · home

On Copal: One of the catalogue's toys, and useful: a banner at the top of a script's output, a login message, a heading in a README.

figlet [ -cklnoprstvxDELNRSWX ] [ -d fontdirectory ]
       [ -f fontfile ] [ -m layoutmode ]
       [ -w outputwidth ] [ -C controlfile ]
       [ -I infocode ] [ message ]

Use

Give it the words; it prints them large. -f chooses the font; showfigfonts shows them all.

Examples

figlet Copalbig text, the standard font
figlet -f slant Copalanother font
figlet -c -w 80 'Hello, world'centred on 80 columns
showfigfonts | lessevery font, as a sample
echo Build done | figletfrom a pipe

Options

-f FONT
the font: standard, slant, banner, big, small, script...
-c
centre the text
-r
right-justify it
-w N
the output width
-t
use the terminal's width
-k
kerning: letters close, not overlapping

Notes

  • The fonts are in /usr/share/figlet/fonts; figlist names them.
  • A long line wraps at 80 columns unless -w or -t says otherwise.

See also fortune, cbonsai

fortune Print a random saying: quotations, jokes, limericks, Star Trek.

Games · command-line tool · fortune 0.1 · stage 12 · The application catalogue · man fortune(6) · home

needs libbsd

On Copal: One of the catalogue's toys, and a tradition: the saying a new terminal greets you with.

fortune [-aefilosw] [-m pattern] [[N%] file/directory/all]

Use

Run it and a saying is printed. Name a collection to choose from it alone; -s keeps it to a line or two.

Examples

fortunea saying
fortune -sa short one
fortune startrekfrom one collection
fortune -m 'computer'every saying that matches
fortune -fthe collections, and their sizes

Options

-s
short sayings only
-l
long ones only
-m PATTERN
print every saying matching PATTERN
-i
ignore case, with -m
-f
list the files it would choose from
-o
only the potentially offensive ones
-a
all of them, offensive included

Notes

  • The collections are in /usr/share/fortune: fortunes, fortunes2, limerick, recipes, startrek, zippy.
  • To greet every new terminal, add fortune -s to the end of ~/.profile.local.

See also cbonsai, figlet

frotz A Z-machine interpreter: plays Infocom's text adventures and everything written for it since.

Games · command-line tool · frotz 2.55 · stage 12 · The application catalogue · man frotz(6) · home

needs libao, libmodplug, libncursesw, libsamplerate, libsndfile

On Copal: The catalogue's interactive-fiction player. It ships with no stories; thousands are free on the Interactive Fiction Archive, and Zork I to III are freely distributed.

frotz [options] file [blorb_file]

At least one file must be specified on the command line.  This can be either a plain Z-code
file or a Blorb file.  A Z-code file is a compiled executable for the Z-Machine.  A Blorb
file contains audio, graphics, and other things in addition to the game wrapped up into a
single file.  It can also optionally contain the Z-Machine executable.  If a plain Z-code
file is supplied, then Frotz will check for a Blorb file with the same base name but an
extension of .blb, .blorb, or .zblorb and load it if found.

If the file supplied on the command line is a Blorb file, then Frotz will check to see if a
Z-code file is contained within.  If not found, then Frotz will complain and exit.

An alternatively-named Blorb file can be supplied as the optional second parameter to the
command line invocation.
...

Use

Give it a story file -- .z3, .z5, .z8 -- and play by typing commands. save and restore work inside the story, to a file you name.

Examples

frotz zork1.z5play
frotz -w 80 story.z8at a fixed width
frotz -d story.z5no colours
look inventory (in the story) the usual commands
save restore to and from a file you name
undo take back the last move, in stories that allow it
quit leave

Options

-d
disable colour
-w N
the screen width
-h N
the screen height
-l N
the left margin
-L FILE
load a saved game at start
-e
enable sound

Notes

  • Where to find stories: ifarchive.org (the Interactive Fiction Archive), and ifdb.org to choose one. Most are one file; download it and play.
  • Glulx stories (.gblorb, .ulx) need a different interpreter; frotz is the Z-machine only.

See also adventure

hangman Hangman, against the system dictionary.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man hangman(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games. It draws its words from /usr/share/dict/words, which Copal links to the English word list.

hangman [-d wordlist] [-m minlen]

Use

Guess the hidden word a letter at a time; seven wrong guesses and the figure is complete.

Examples

hangmanplay, words from the system dictionary
hangman -m 8only words of 8 letters or more
hangman -d words.txtwords from your own list

Options

-d FILE
the word list (default /usr/share/dict/words)
-m N
the shortest word length

Notes

  • "unable to open dictionary file /usr/share/dict/words" means the word list is missing: stage 18 links it to american-english from words-en.

See also fortune, robots

klondike Klondike solitaire, in a terminal, with the keyboard.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man klondike(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games: patience for a terminal session.

Use

The standard patience: build the foundations up by suit from the aces, moving cards between the seven columns in descending, alternating colours. Keys name the piles; the screen lists them.

Examples

klondikeplay

Options

Notes

  • The keys are shown on the screen as you play; ? if they are not.
  • ttysolitaire is the same game drawn with box characters, and it counts passes through the deck.

See also ttysolitaire

moon-buggy Drive a buggy across the moon, jumping craters and blasting rocks -- in a terminal.

Games · terminal program · moon-buggy 1.0.51 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man moon-buggy(6) · home

needs libncursesw

On Copal: The store's terminal arcade game: one key to jump, one to fire, and it gets faster. Playable anywhere, over SSH included.

moon-buggy [-hnsV] [--help] [--no-title] [--show-scores] [--version]

Use

The buggy drives itself; jump over the craters with Space and clear rocks with the laser. The timing of a jump is fixed, so the skill is choosing when.

Examples

moon-buggyplay
moon-buggy -nskip the title screen
moon-buggy -sthe high scores, and exit
Space j (in the game) jump
a l fire the laser
q quit (the score is kept)

Options

-n, --no-title
no title screen
-s, --show-scores
print the high scores and exit
-m, --mesg
keep other users' messages off the screen

Notes

  • A jump can only start with the wheels on the ground: jumping early is the usual way to land in the next crater.
  • It comes from Alpine's testing repository (moon-buggy@testing).

See also robots, snake, nethack

nethack NetHack: the deepest of the roguelikes -- a dungeon of letters, and everything interacts.

Games · terminal program · nethack 3.6.7 · stage 12 · The application catalogue · man nethack(6) · home

needs libncursesw

On Copal: The catalogue's first roguelike and its deepest: a game people have played for thirty-five years, in any terminal, over SSH included.

nethack [ -d directory ] [ -n ] [ -p profession ] [ -r race ] [ -[DX] ] [ -u playername ] [
-dec ] [ -ibm ] [ --showpaths ] [ --version[:paste] ]

nethack [ -d directory ] -s [ -v ] [ -p profession ] [ -r race ] [ playernames ]

Use

Pick a role, a race and a name, and descend to retrieve the Amulet of Yendor. You are the @. Every key is a command; ? lists them. Death is permanent, and there is a lot of it.

Examples

nethackplay
nethack -u Rodneyplay as Rodney (and resume his save)
nethack -sthe high scores
h j k l y u b n (in nethack) move, including diagonally
i , d inventory / pick up / drop
spray search / pray (once in a while)
S save and quit; ? help

Options

-u NAME
the character's name; a saved game of that name resumes
-s
show the scores
-p ROLE
choose the role: Valkyrie, Wizard, Samurai...
-X
explore mode: no death, no score

Notes

  • Options go in ~/.nethackrc: OPTIONS=number_pad:1 for the numeric keypad, OPTIONS=color, OPTIONS=autopickup,pickup_types:$.
  • S saves; next time, the same name picks up where you left.
  • A Valkyrie is the gentlest start.

See also brogue, angband, zangband

robots Escape the robots: every move, they step toward you, and collide into junk.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man robots(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games: a five-minute puzzle, in any terminal, with a score table.

Use

Robots (+) move one step toward you (@) each turn. When two collide, or one walks into a junk heap (*), they die: a point each. Clear the field and the next one starts. You have no weapon, only a teleporter.

Examples

robotsplay
h j k l y u b n (in the game) move, diagonals included
. or Space stay where you are for a turn
t teleport, somewhere random
q quit

Options

Notes

  • Standing still is a move: the robots close in and, lined up right, pile into each other.
  • Scores are shared in /usr/share/bsdgames by the group users; Copal links the path the game expects and adds you to the group from 24 Sep 2026. Before that, a score was shown and then lost.

See also snake, atc, nethack

sl A steam locomotive crosses the screen -- for when you typed sl instead of ls.

Games · command-line tool · sl 5.02 · stage 12 · The application catalogue · man sl(1) · home

needs libncursesw

On Copal: One of the catalogue's toys: the classic punishment for a typo. It cannot be interrupted, which is the point.

sl [ -alFc ]

Use

Mistype ls as sl, and wait.

Examples

sla train
sl -la little one
sl -Fit flies
sl -aan accident

Options

-a
an accident: people cry for help
-l
a little locomotive
-F
it flies
-c
C51 instead of D51

Notes

  • Ctrl-C does not stop it. It ends when the train has passed.

See also cmatrix, asciiquarium

snake Collect the money and reach the exit, with a snake after you.

Games · terminal program · bsd-games 3.3 · stage 4 · X.Org, i3, a terminal and a browser · man snake(6) · home

needs libncursesw

On Copal: Part of the catalogue's BSD games: not the phone game, the older one, where you are the one being chased.

snake [width height] [-s]

Use

You are the @. Pick up the money ($) -- a new one appears each time -- and leave through the exit (#) before the snake (S and its s body) catches you. As you get richer, the snake gets hungrier.

Examples

snakeplay, on the whole screen
snake 60 20a smaller field: width, height
snake -sthe scores, and exit
h j k l or arrows (in the game) move
Space warp out of a tight spot, at a price

Options

WIDTH HEIGHT
the size of the field (default: the screen)
-s
print the scores and exit

Notes

  • Only leaving by the exit scores. Being eaten is worth nothing.
  • Scores go in the shared table (/usr/share/bsdgames), kept from 24 Sep 2026 for members of users, which Copal adds you to.

See also robots, atc

ttysolitaire Klondike solitaire drawn with box characters, played with vi keys.

Games · terminal program · tty-solitaire 1.4.1 · stage 12 · The application catalogue · home

needs libncursesw

On Copal: The catalogue's nicer-looking terminal patience: real card shapes in any terminal, over SSH included.

Use

Standard Klondike: build down in alternating colours on the seven columns, up by suit from the aces on the foundations. The cursor moves between piles; a card is picked up and put down with one key.

Examples

ttysolitaireplay
ttysolitaire -p 1one pass through the deck: harder
ttysolitaire --four-color-decka colour per suit

Options

-p, --passes N
passes through the deck (default 3)
--four-color-deck
a distinct colour for each suit
--no-background-color
no green table

Notes

  • The command is ttysolitaire, one word; the package is tty-solitaire.
  • It installs no documentation; the keys are in the README at github.com/mpereira/tty-solitaire.

See also klondike

zangband ZAngband: Angband with a wilderness, towns, and Zelazny's Amber above the dungeon.

Games · terminal program · zangband 2.7.5.1 · stage 12 · The application catalogue · home

needs ncurses, libncursesw

On Copal: The catalogue's sprawling Angband variant: a whole overworld of towns and dungeons rather than one town and one descent.

Use

Make a character, walk the wilderness between towns, and pick which dungeons to take on. ? is the help and = the options, as the title screen says.

Examples

zangbandplay
arrows / hjkl (in zangband) move
? = help / options
g i w pick up / inventory / wield
< > stairs up / down
Ctrl-X save and quit

Options

-n
a new character
-u<name>
play the character NAME: zangband -uRodney

Notes

  • It starts only for a member of the group users, which owns its score and save directories: otherwise "Cannot create the '/usr/lib/zangband/apex/scores.raw' file!" and a fatal error. Copal adds you from 24 Sep 2026; before that, doas adduser $USER users, then log out and in.
  • Saves are shared in /usr/lib/zangband/save, by character name.

See also angband, nethack, brogue

Graphics

tesseract OCR: read the text in a picture of a page, and write it as text or a searchable PDF.

Graphics · command-line tool · tesseract-ocr 5.5.2 · stage 12 · The application catalogue · home

needs cairo, fontconfig, glib, libgomp, harfbuzz, icu-libs, leptonica, pango

On Copal: The catalogue's optical character recogniser, with English. It turns scans and screenshots into text you can search, copy and edit.

Usage:
  /usr/bin/tesseract --help | --help-extra | --version
  /usr/bin/tesseract --list-langs
  /usr/bin/tesseract imagename outputbase [options...] [configfile...]

Use

Give it an image and an output name: it writes NAME.txt. Put - as the name for the terminal, and add pdf at the end for a PDF with the text under the picture. Clean, straight, 300 dpi scans read best.

Examples

tesseract scan.png outout.txt
tesseract scan.png - | lessto the terminal
tesseract scan.png out pdfout.pdf, searchable
tesseract photo.jpg - --psm 6one block of text: signs, labels
pdftoppm -r 300 -png scan.pdf pg && for f in pg-*.png; do tesseract $f - ; done > scan.txt
tesseract --list-langsthe languages installed

Options

-l LANG[+LANG]
the language(s): eng, or eng+deu
--psm N
page segmentation: 3 automatic, 6 one block, 7 one line
--dpi N
the resolution, when the image does not say
--list-langs
the installed languages pdf / hocr / tsv the output formats, named after the output base

Notes

  • It needs a language's data to do anything: "Failed loading language 'eng'" means tesseract-ocr-data-eng is missing. Copal installs it with the catalogue row from 24 Sep 2026; before that, doas apk add tesseract-ocr-data-eng. Other languages are tesseract-ocr-data-deu and so on.
  • A photo at an angle or in low light reads badly: crop, straighten and raise the contrast first.
  • Not on the 32-bit Pis (armv6, armhf): the row is gated off there.

See also pdftotext, copal-shot

Instruments

fftw-wisdom Pre-compute FFTW's "wisdom": the fastest way to do given Fourier transforms on this machine.

Instruments · command-line tool · fftw 3.3.11 · stage 12 · The application catalogue · man fftw-wisdom(1) · home

needs fftw-double-libs, fftw-single-libs, fftw-long-double-libs

On Copal: The catalogue's FFTW tool: programs built on FFTW -- rtl_power_fftw, GNU Radio, Octave -- start their transforms faster, and run them faster, when this machine's best plans are measured once and saved.

fftw-wisdom [OPTION]... [SIZE]...

Use

Name the transform sizes you use; it measures the options on this CPU and writes the result, which FFTW-based programs load. Measuring takes a while; using it is free.

Examples

fftw-wisdom -v -c -o wisdomcommon sizes, measured, into ./wisdom
fftw-wisdom -v -o wisdom cof1024 cof4096just these (complex, out-of-place, forward)
doas fftw-wisdom -c -o /etc/fftw/wisdomthe system-wide file programs read

Options

-c
the common sizes
-o FILE
write the wisdom to FILE (default stdout)
-t HOURS
time limit for the measuring
-v
verbose
-x
exhaustive: slowest to make, best plans

Notes

  • Sizes are written as a type and a number: c complex or r real, o out-of-place or i in-place, f forward or b backward -- cof1024.
  • Wisdom is for this CPU: made on a Pi 5, it is wrong for a Pi Zero.

See also rtl_power_fftw, octave

sigrok-cli Capture from logic analysers, oscilloscopes and meters, and decode protocols: I2C, SPI, UART...

Instruments · command-line tool · sigrok-cli 0.7.2 · stage 12 · The application catalogue · man sigrok-cli(1) · home

needs glib, libsigrok, libsigrokdecode

On Copal: The catalogue's instrument front end: a cheap USB logic analyser and sigrok turn a Pi into a bench tool that decodes what flows on a circuit's wires.

sigrok-cli [OPTIONS] [COMMAND]

Use

--scan finds the instruments attached. Choose one with -d, capture a number of samples or a time, and decode with -P, or save the capture to open in PulseView, sigrok's window.

Examples

sigrok-cli --scanthe instruments connected
sigrok-cli -d fx2lafw --samples 1M -c samplerate=4M -o cap.srcapture to a file
sigrok-cli -i cap.sr -P uart:baudrate=9600 -A uartdecode a saved capture as serial
sigrok-cli -d demo --samples 20 -O asciitry it with the demo device
sigrok-cli -Levery driver, format and decoder

Options

-d DRIVER
the instrument driver (demo, fx2lafw, rigol-ds...)
-c KEY=VALUE
device settings: samplerate, voltage...
--samples N
capture N samples; --time MS or for a time
-C CHANNELS
which channels -i FILE / -o FILE read / write a capture file
-O FORMAT
output format: bits, hex, ascii, csv, vcd...
-P DECODER
a protocol decoder, with its options
--scan
find devices; -L list what is supported

Notes

  • The demo driver needs no hardware: the place to learn the options.
  • A USB instrument needs permission to open; if --scan finds nothing with it plugged in, try once with doas to see whether that is why.

See also pulseview, rigctl

Internet

lftp A file-transfer shell for FTP, SFTP and HTTP: mirror folders, resume, queue.

Internet · terminal program · lftp 4.9.3 · stage 12 · The application catalogue · man lftp(1) · home

needs libcrypto3, libncursesw, readline, libssl3, zlib

On Copal: The catalogue's terminal FTP client. It speaks SFTP over ssh too, and mirrors a whole folder in either direction -- the tool for a web host or an old server that offers only FTP.

Use

Connect, then work with ls, cd, get and put as in a shell. The command to know is mirror: it copies a whole directory tree down, or up with -R, sending only what changed.

Examples

lftp sftp://you@example.orgconnect over SFTP
lftp ftp://ftp.example.organonymous FTP
lftp -u you ftp.example.orgFTP with a password prompt
lftp -c 'open sftp://you@host; mirror site/ ~/site'one command, then quit
mirror REMOTE LOCAL (in lftp) download a tree
mirror -R LOCAL REMOTE upload one
pget -n 4 big.iso a file in four parallel pieces
get -c file resume a download
jobs / bye running transfers / quit

Options

-u USER[,PASS]
log in as USER
-p PORT
the port
-c COMMANDS
run these and exit
-f FILE
run a script of commands
-e COMMANDS
run these, then stay

Notes

  • Plain ftp:// sends the password in the clear. Use sftp:// wherever the server has ssh.
  • mirror without --delete only adds and updates; with it, it removes what the source lacks. Try mirror --dry-run first.
  • Settings go in ~/.config/lftp/rc (or ~/.lftp/rc if that exists), bookmarks with bookmark add NAME.

See also rsync, curl, ssh

lynx The oldest text web browser still maintained: web and Gopher, keyboard only.

Internet · terminal program · lynx 2.9.3 · stage 12 · The application catalogue · man lynx(1) · home

needs libbz2, libcrypto3, libintl, libncursesw, libssl3, zlib

On Copal: One of the catalogue's text browsers, kept at every level for use over SSH or on a console. It reads Gopher as well as the web, and its -dump is the classic way to turn a page into text.

lynx [options] [optional paths or URLs]

lynx [options] [path or URL] -get_data
data
--

lynx [options] [path or URL] -post_data
data
--

Use “lynx -help” to display a complete list of current options.

Use

Arrows move between links: down and up to the next link, right to follow it, left to go back. It shows a page as a line of text at a time, with no columns or tables laid out, which makes it the most readable of the text browsers with a screen reader.

Examples

lynx https://lite.duckduckgo.combrowse
lynx gopher://gopher.floodgap.comGopher
lynx -dump https://example.comthe page as text, links numbered at the end
lynx -dump -listonly URLonly the list of links
lynx -source URL > page.htmlthe HTML
g (in the browser) go to a URL
/ search the page
o options; q quit

Options

-dump
print the rendered page and quit
-listonly
with -dump: the links only
-nolist
with -dump: no link list at the end
-source
print the HTML
-width N
the width -dump lays out to
-accept_all_cookies
no questions about each cookie

Notes

  • It asks about every cookie. -accept_all_cookies, or set it in o (options) and save.
  • No JavaScript and no CSS: the page is the page's text, in order. For a site built for phones, that is often the best way to read it.

See also links, elinks, w3m, curl

retawq A tiny multi-window text web browser, with a split screen.

Internet · terminal program · retawq 0.2.6c · stage 12 · The application catalogue · man retawq(1) · home

needs libcrypto3, libncursesw, libssl3

On Copal: The smallest of the catalogue's text browsers, kept at every level: it keeps several pages open at once and shows two side by side, which the others do not.

Use

Open a page, then more windows with n, and split the screen with 2 to read two at once. Most commands are one key; Escape cancels any of them.

Examples

retawq https://example.combrowse
retawq URL1 URL2two documents at once
retawq --dump=https://example.comthe page as text, to stdout
retawq --download=URL > filefetch a file, no display
g (in the browser) go to a URL
n C a new window / close this one
2 1 split the screen / un-split it; Tab between halves
b u bookmarks / the history of URLs
Q quit

Options

--dump=URL
render the page, write it to stdout, quit
--download=URL
write the content of URL to stdout, quit
--colors=off
no colours
--console
console mode: line by line, no full screen

Notes

  • It is from 2006 and speaks older HTML well and newer HTML less so; a modern site may come out as a column of text in the wrong order.
  • The full key list is in /usr/share/doc/retawq/key.html -- open it in retawq itself.

See also links, lynx, w3m

speedtest-cli Measure the connection's download speed, upload speed and ping, against speedtest.net.

Internet · command-line tool · speedtest-cli 2.1.3 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs python3

On Copal: The store's line test: from a Pi with no browser, is the network slow, or is it something else?

usage: speedtest-cli [-h] [--no-download] [--no-upload] [--single] [--bytes]
                     [--share] [--simple] [--csv]
                     [--csv-delimiter CSV_DELIMITER] [--csv-header] [--json]
                     [--list] [--server SERVER] [--exclude EXCLUDE]

Use

Run it; it picks the nearest speedtest.net server, measures latency, then download and upload, and prints the results.

Examples

speedtest-clithe full test, with progress
speedtest-cli --simplethree lines: ping, download, upload
speedtest-cli --list | headservers near you, with their IDs
speedtest-cli --server 12345test against one server
speedtest-cli --json > result.jsonmachine-readable, for a log

Options

--simple
only ping, download and upload
--list
nearby servers and their IDs
--server ID
use this server
--no-upload
skip the upload test
--bytes
show bytes per second instead of bits
--json / --csv
output for scripts
--share
a link to a result image on speedtest.net

Notes

  • Over wifi, the result measures the wifi as much as the line: compare with a cable before blaming the provider.
  • A test transfers tens of megabytes; on a metered connection, run it sparingly.

See also curl, ip, iw

w3m A text web browser and pager: tables laid out, good forms, and it pages files too.

Internet · terminal program · w3m 0.5.6 · stage 12 · The application catalogue · man w3m(1) · home

needs libcrypto3, gc, libncursesw, libssl3, zlib

On Copal: One of the catalogue's text browsers, kept at every level. It lays out tables and fills forms better than the others, and doubles as a pager: w3m file.html, or HTML piped into it.

w3m [OPTION]... [ file | URL ]...

Use

Browse with the keyboard, or read HTML from a file or a pipe. It keeps several pages open as tabs, and its forms handle searches and sign-ins that the simpler browsers stumble on (as long as they need no JavaScript).

Examples

w3m https://lite.duckduckgo.combrowse
w3m README.htmla local HTML file
curl -s URL | w3m -T text/htmlHTML from a pipe
w3m -dump https://example.comthe page as text
w3m -dump -cols 72 URL > page.txtat a fixed width
U (in the browser) open a URL
Enter follow the link; B back
T a new tab; { } between tabs
/ search; q quit (Q without asking)

Options

-dump
print the rendered page and quit
-cols N
the width for -dump
-T TYPE
the content type of stdin: text/html
-o OPT=VAL
set an option for this run
-M
monochrome

Notes

  • Arrow keys move the cursor, not the page: Space and b page down and up. Links are followed where the cursor is.
  • o is the options page; changes saved there go to ~/.w3m/config.

See also links, elinks, lynx

Languages

cargo Rust's build tool and package manager: new, build, run, test, install.

Languages · command-line tool · cargo 1.96.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man cargo(1) · home

needs rust, libcrypto3, libcurl, scudo-malloc, sqlite-libs, libssh2, libssl3, zlib

On Copal: Stage 7 installs Rust on every port, the Zero included, and several checkouts in ~/code are Rust: copal-build compiles them with cargo and links what they make into ~/.local/bin.

cargo [options] command [args]
cargo [options] --version
cargo [options] --list
cargo [options] --help
cargo [options] --explain code

Use

Every Rust project is a directory with a Cargo.toml. cargo run builds and runs it; cargo build --release makes the fast version in target/release. Dependencies named in Cargo.toml are fetched from crates.io and built with it.

Examples

cargo new hello && cd helloa new project, with git
cargo runbuild (debug) and run
cargo build --releaseoptimised, into target/release/
cargo checktype-check only: much faster than a build
cargo testrun the tests
cargo clippylints: common mistakes, better idioms
cargo fmtformat the code
cargo install ripgrepbuild a tool into ~/.cargo/bin (on PATH)

Options

new NAME
a new project (--lib for a library)
build / run
compile / compile and run; --release for optimised
check
check without producing a binary
test
build and run the tests
clippy / fmt
lint / format
add CRATE
add a dependency to Cargo.toml
install CRATE
build and install a program
-j N
parallel jobs
--offline
use only what is already downloaded

Notes

  • This is Alpine's Rust, a release or two behind. A crate that says "requires rustc 1.NN or newer" wants rustup -- and once rustup is in, ~/.cargo/bin comes first on PATH and its cargo replaces this one. which cargo says which you are running.
  • rustc is an LLVM compiler and hungry: a release build with dependencies can want more than 512 MB. On a Zero it works because of zram, slowly; -j1 keeps it from running out.
  • cargo build without --release makes a debug build that can run ten times slower. Measure the release one.

See also gdb, git, make, copal-build

clang The LLVM C and C++ compiler: gcc's rival, with clearer errors.

Languages · command-line tool · clang22 22.1.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man clang(1) · home

needs clang22-headers, clang22-libs, fortify-headers, libgcc-static, libstdc++-dev, llvm22-linker-tools, musl-dev, llvm22-libs

On Copal: Stage 7's second compiler, and it brings clangd -- the language server that gives Neovim go-to-definition, references and the call hierarchy in C and C++.

Use

Compile C (clang) or C++ (clang++) with the same flags as gcc. Worth running a program through both: each warns about things the other misses, and clang's messages point at the exact column.

Examples

clang -Wall -Wextra -g hello.c -o hellocompile, like gcc
clang++ -std=c++20 main.cpp -o mainC++
clang -fsyntax-only -Wall file.ccheck, produce nothing
CC=clang makea Makefile's build, with clang
clang --versionwhich LLVM
clang-format -i file.creformat in place

Options

-o FILE
name the output
-g
debug information
-O2
optimise
-Wall -Wextra
warnings
-Weverything
every warning clang has (noisy, but thorough)
-std=c17
the language standard, as gcc
-fsyntax-only
parse and check, write nothing

Notes

  • clangd needs to know the flags: a compile_commands.json at the project root. bear -- make records one from a Makefile build, and cmake writes one with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON.
  • Sanitizers: as with gcc, the ASan and UBSan runtimes are missing; -fsanitize=undefined -fsanitize-trap=undefined needs none, and stops the program at the first undefined behaviour.
  • Clang links with the system's gcc toolchain and musl, so its programs and gcc's mix freely.

See also gcc, make, cmake, nvim, gdb

clangd The C and C++ language server: completion, go-to-definition, errors as you type.

Languages · command-line tool · clang22-extra-tools 22.1.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs clang22, llvm22-libs, clang22-libs

On Copal: Stage 7 installs it with clang-format (clang22-extra-tools), and Neovim, Helix and Geany talk to it: it is what makes gd, gr and K work in C and C++.

USAGE: clangd [options]
OPTIONS:

Use

You rarely run it yourself: the editor starts it. What it needs from you is the project's build flags, in a compile_commands.json at the root of the project; without one it guesses, and gets includes wrong.

Examples

bear -- makerecord compile_commands.json from a make build
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ONor have cmake write it
ln -s build/compile_commands.json .where clangd looks for it
clangd --check=src/main.ctry it on one file, from the shell
clang-format -i src/*.cits companion: reformat in place

Options

--check=FILE
parse FILE and report what clangd sees
--compile-commands-dir=DIR
where compile_commands.json is
--background-index
index the whole project in the background
--log=verbose
more detail in the editor's log

Notes

  • A .clangd file in the project sets flags without a build system: CompileFlags: { Add: [-std=c17, -Iinclude] }.
  • In Neovim, :Lsp says whether it is running for the current file.

See also clang, nvim, hx, bear

composer PHP's dependency manager: fetch the libraries a project needs, and autoload them.

Languages · command-line tool · composer 2.10.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs php85, php85-phar, php85-curl, php85-iconv, php85-mbstring, php85-openssl, php85-zip, p7zip

On Copal: Part of the catalogue's PHP 8.3 row, with Xdebug: for writing PHP programs and trying frameworks on the Pi. The row installs PHP for development, not as a public server.

Usage:
  list [options] [--] [<namespace>]
Arguments:

Use

In a project, composer require adds a library and installs it into vendor/; composer install installs exactly what composer.lock records. Your code includes vendor/autoload.php once.

Examples

composer inita composer.json for this folder
composer require monolog/monologadd a library
composer installinstall what composer.lock says
composer updatemove to newer allowed versions
composer create-project laravel/laravel appa new project from a package

Options

init
create composer.json
require PKG
add and install a package
install
install from composer.lock
update
update within composer.json's limits
dump-autoload
regenerate the autoloader
create-project P
start a project from package P

Notes

  • Commit composer.lock: it is what makes install give everyone the same versions.
  • PHP modules a library needs (php83-mbstring, php83-pdo...) are apk packages; composer check-platform-reqs names the missing ones.

See also php83

crystal Crystal: Ruby-like syntax, static types inferred, compiled to fast native code.

Languages · command-line tool · crystal 1.20.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man crystal(1) · home

needs gc-dev, gcc, gmp-dev, libatomic_ops, musl-dev, pcre2-dev, llvm22-libs, libffi

On Copal: The catalogue's Crystal, on the 64-bit boards: for people who like writing Ruby and want a compiled, typed program at the end.

crystal command [switches] programfile — [arguments]

Use

crystal run compiles and runs a file; crystal build --release makes an optimised program. crystal init app NAME starts a project with its shard.yml.

Examples

crystal run hello.crcompile and run
crystal hello.crthe same: run is the default
crystal build --release hello.cran optimised program, ./hello
crystal eval 'puts 6 * 7'one line
crystal init app myappa new project

Options

run FILE
build and run (the default)
build FILE
build an executable; --release to optimise
eval CODE
evaluate CODE
init app NAME
start a project
spec
run the tests in spec/

Notes

  • shards, its dependency manager, is not installed here.
  • A release build of anything sizeable is slow and memory-hungry on a Pi; develop without --release, release at the end.
  • 64-bit only: its catalogue row is gated to aarch64 and x86_64.

See also ruby, nim, go

csi CHICKEN Scheme's interpreter -- and csc, which compiles Scheme to C and to programs.

Languages · terminal program · chicken 5.4.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man csi(1) · home

needs gcc, libc-dev, chicken-dev, chicken-libs

On Copal: The catalogue's compiling Scheme: try code in csi, then turn it into a small native program with csc, through C.

csi [OPTION ...] [FILENAME ...]

Use

csi is the interactive interpreter and runs scripts; csc compiles a file to an executable. Libraries ("eggs") install with chicken-install.

Examples

csithe REPL; ,q to leave
csi -s script.scmrun a file as a script
csi -e '(print (* 6 7))'one expression
csc hello.scmcompile to ./hello
chicken-install -s srfi-1an egg, system-wide (as root)

Options

-s FILE
run FILE as a script, then exit
-e EXPR
evaluate EXPR and exit
-q
no banner
-n
do not load ~/.csirc

Notes

  • The command names are CHICKEN's own: csi interprets, csc compiles; there is no chicken command to run.
  • csc needs a C compiler; stage 7's gcc is it.

See also guile, racket, gcc

dlv Delve: the debugger for Go -- breakpoints, stepping, goroutines.

Languages · command-line tool · delve 1.26.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

On Copal: The catalogue's Go debugger. gdb can step through Go but does not understand goroutines, interfaces or Go's types; Delve does.

Usage:
  dlv [command]
Available Commands:

Use

dlv debug builds the package in the current folder with debugging on and stops before main. Set breakpoints, continue, and look around at the (dlv) prompt.

Examples

dlv debugbuild and debug the package here
dlv debug -- -v input.txtwith arguments for the program
dlv testdebug the package's tests
dlv exec ./servera binary built already
doas dlv attach $(pidof server)a running process
break main.main (at the prompt) a breakpoint; b file.go:42 for a line
continue run to it (c)
next / step over / into
print x a value (p)
goroutines every goroutine; exit leave

Options

debug [PKG]
build and debug
test [PKG]
debug the tests
exec BINARY
debug a built binary
attach PID
attach to a running process
core BIN CORE
examine a core dump

Notes

  • 64-bit only: its catalogue row is gated to aarch64 and x86_64.
  • Build with optimisations off to follow the source line by line: dlv debug does this for you; for exec, build with go build -gcflags=all="-N -l".

See also go, gdb

dotnet The .NET 9 SDK: create, build and run C#, F# and VB programs.

Languages · command-line tool · dotnet-host 10.0.12 · stage 12 · The application catalogue · home

On Copal: The catalogue's .NET, wherever Microsoft builds it -- not on ARMv6 or 32-bit x86. C# console programs and web services run on a Pi.

Usage: dotnet [runtime-options] [path-to-application] [arguments]
Execute a .NET application.

Use

dotnet new makes a project from a template, dotnet run builds and runs it, dotnet publish makes a folder to copy to another machine.

Examples

dotnet new console -o hello && cd helloa new C# console program
dotnet runbuild and run it
dotnet add package Newtonsoft.Jsona NuGet package
dotnet publish -c Release -o outa release build into out/
dotnet new listthe templates there are

Options

new TEMPLATE
create a project (console, classlib, web, ...)
run
build and run the project here
build
build it
add package P
add a NuGet package
publish
produce a deployable folder
test
run its tests

Notes

  • It sends usage statistics to Microsoft unless DOTNET_CLI_TELEMETRY_OPTOUT=1 is set; put the export in ~/.profile.local to keep it.
  • The first dotnet new or run is slow while it sets up; later ones are quicker.

See also pwsh, java

elixir Elixir: a friendly functional language on the Erlang VM, built for concurrency.

Languages · terminal program · elixir 1.19.6 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man elixir(1) · home

needs erlang, erlang-dev

On Copal: The catalogue's Elixir, with iex for trying things and mix for projects: millions of lightweight processes, on a Pi.

elixir [OPTIONS] file ...

Use

iex is the interactive shell. elixir runs a script (.exs). mix creates, builds, tests and runs projects.

Examples

iexthe interactive shell; Ctrl-C twice to leave
elixir script.exsrun a script
elixir -e 'IO.puts 6 * 7'one expression
mix new hello && cd helloa new project
mix testits tests; mix run to run it

Options

-e CODE
evaluate CODE
-r FILE
require FILE first
--no-halt
keep the VM running after the script
-v, --version
the Elixir and Erlang versions

Notes

  • mix deps.get fetches dependencies from hex.pm; the first time it asks to install Hex itself -- answer yes.
  • It is Erlang underneath: erl is also here, and Erlang libraries work from Elixir.

See also ruby, erlang

fpc Free Pascal: a compiler for Pascal and Object Pascal, Turbo Pascal and Delphi dialects included.

Languages · command-line tool · fpc 3.2.2 · stage 12 · The application catalogue · man fpc(1) · home

On Copal: The catalogue's Pascal: old Turbo Pascal programs and new Object Pascal ones compile here, quickly, into small native programs.

fpc [options] [sourcefile]

Use

Give it a .pas file; it writes a program named after it. A mode switch chooses the dialect when compiling older code.

Examples

fpc hello.pascompile; run with ./hello
fpc -O2 prog.pasoptimised
fpc -Mtp old.pasin Turbo Pascal mode
fpc -Mdelphi unit.pasin Delphi mode
fpc -g prog.paswith debug information

Options

-o<NAME>
the output name (no space: -ohello)
-O1 / -O2
optimisation levels
-g
debug information
-M<MODE>
dialect: fpc, objfpc, tp, delphi
-Fu<DIR>
where to find units
-h
every option

Notes

  • Options take their value with no space: -ohello, -Fu./units.
  • It comes from Alpine's testing repository (fpc@testing).

See also gcc

gfortran The GNU Fortran compiler: FORTRAN 77 through Fortran 2018.

Languages · command-line tool · gfortran 15.2.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man gfortran(1) · home

needs gcc, libgfortran, gmp, isl25, mpc1, mpfr4, zlib

On Copal: Stage 7's Fortran, for numerical code old and new -- and the compiler R and SciPy-style builds need for their Fortran parts.

gfortran [-c|-S|-E]
         [-g] [-pg] [-Olevel]
         [-Wwarn...] [-pedantic]
         [-Idir...] [-Ldir...]
         [-Dmacro[=defn]...] [-Umacro]
         [-foption...]
         [-mmachine-option...]
         [-o outfile] infile...

Only the most useful options are listed here; see below for the remainder.

Use

Compile .f90 (free form) or .f (fixed form, FORTRAN 77) files as gcc compiles C. The standard is chosen with -std.

Examples

gfortran -Wall -g hello.f90 -o hellocompile, warnings on
gfortran -O2 -std=f2018 model.f90 -o modeloptimised, Fortran 2018
gfortran -std=legacy old.f -o olda FORTRAN 77 program
gfortran -c util.f90 && gfortran main.f90 util.o -o progmodules, then link
gfortran -fcheck=all -g prog.f90run-time bounds checking

Options

-o FILE
the output
-g
debug information
-Wall
warnings
-std=STD
legacy, f95, f2003, f2008, f2018
-fcheck=all
check array bounds and more at run time
-ffree-form / -ffixed-form
override what the extension says

Notes

  • A module's .mod file is written where it is compiled: compile the modules before the programs that use them.
  • Optimisation levels (-O2, -O3) are gcc's, shared by every language it compiles: man gcc documents them.
  • -fcheck=all finds the out-of-bounds errors that are silent otherwise; keep it for debugging, it slows the program.

See also gcc, gdb, make

ghc The Glasgow Haskell Compiler, with ghci for trying things and cabal for projects.

Languages · command-line tool · ghc 9.10.3 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs gmp-dev, libffi-dev, perl, gcc, llvm15, clang16, libffi, gmp

On Copal: The catalogue's Haskell, on the 64-bit Pis and PCs. GHC is not built for 32-bit ARM at all -- it bootstraps from an earlier GHC -- so on a Zero the nearest in spirit is OCaml.

Usage:
    ghc-9.10.3 [command-line-options-and-input-files]

Use

ghci is the interactive prompt, where most learning happens. ghc compiles a file to a program. cabal makes, builds and runs projects with their dependencies.

Examples

ghcithe prompt: :t for a type, :q to leave
runghc Main.hsrun a file without compiling it
ghc -O2 Main.hs -o maincompile a program
cabal initstart a project here
cabal update && cabal runfetch the package list, build and run

Options

-o FILE
the output
-O
optimise (-O2 for more)
-Wall
warnings
--make
build a program and its modules (the default)
-i DIR
search DIR for modules

Notes

  • cabal update is needed once before any package can be installed.
  • A first cabal build of a project with dependencies compiles them all: on a Pi, that is a long wait and a lot of memory -- zram helps.

See also hlint, ocaml

go The Go toolchain: build, run, test and fetch Go programs.

Languages · command-line tool · go 1.26.8 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man go(1) · home

needs binutils, gcc, musl-dev

On Copal: Stage 7 installs Go on every port, with gopls for Neovim. Several of the terminal programs Copal ships are Go, and Go is the easiest way to build one program for every Pi from one machine.

go command [arguments]

Use

A Go project is a module: a directory with go.mod. go run . builds and runs it, go build leaves a single static binary, and go install builds a program from the internet into ~/go/bin.

Examples

go mod init example.com/hellostart a module here
go run .build and run it
go build -o hello .a binary called hello
go test ./...every package's tests
go install github.com/charmbracelet/glow@latesta tool, into ~/go/bin
GOOS=linux GOARCH=arm GOARM=6 go build -o hello-zero .for a Pi Zero
go env GOPATHwhere downloads and installs go

Options

run .
build and run the package here
build -o FILE
compile to FILE
test ./...
run tests, recursively
install PKG@VER
build and install a program
mod init PATH
start a module
mod tidy
add missing and remove unused dependencies
fmt ./...
format the code (gofmt)
vet ./...
report suspicious code
env
the toolchain's settings; GOOS, GOARCH, GOARM, CGO_ENABLED

Notes

  • Cross-compiling is the trick: set GOOS, GOARCH (arm64, arm, amd64) and for 32-bit ARM GOARM (6 for a Zero, 7 for a Pi 2), and the binary runs there -- as long as CGO_ENABLED=0 or no C is involved.
  • ~/go/bin is on PATH on a Copal machine; Alpine alone does not put it there.
  • A program that uses C through cgo needs gcc and links against musl; such a binary will not run on a glibc system.

See also gdb, dlv, git, cargo

guile GNU Guile: a Scheme for scripting, extending programs, and learning Lisp.

Languages · terminal program · guile 3.0.9 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man guile(1) · home

needs guile-libs

On Copal: The catalogue's Scheme from the GNU project -- the extension language of GNU programs, and a good first Lisp with a helpful REPL.

guile [-L DIRECTORY] [-l FILE] [-e FUNCTION] [\] [-c EXPR] [-s SCRIPT] [--] [SCRIPT
[ARGs for SCRIPT]]

Only the most useful options are listed here; see below for the remainder.

Use

Start the REPL and type expressions, or run a file of Scheme. Commands to the REPL itself start with a comma.

Examples

guilethe REPL; ,q to leave
guile script.scmrun a file
guile -c '(display (* 6 7)) (newline)'one expression
guile -L . -l lib.scmload a file, with this folder on the path
(define (square x) (* x x)) (at the REPL) define
(map square '(1 2 3)) => (1 4 9)
,help the REPL's own commands

Options

-c EXPR
evaluate EXPR and exit
-l FILE
load FILE
-L DIR
add DIR to the module search path
-s FILE
run FILE as a script
--no-auto-compile
do not cache compiled files

Notes

  • The first run of a file compiles it and caches the result under ~/.cache/guile; later runs start faster.
  • guile-readline gives the REPL history and line editing: (use-modules (ice-9 readline)) (activate-readline) in ~/.guile.

See also csi, racket, sbcl

hlint Suggest better Haskell: simpler expressions, library functions you missed.

Languages · command-line tool · hlint 3.10 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs libffi, gmp

On Copal: The catalogue's Haskell linter, the usual companion to GHC: it teaches idiomatic Haskell as it points things out.

Use

Run it on a file or a folder; it prints each suggestion with the code as it is and as it could be.

Examples

hlint Main.hssuggestions for one file
hlint src/a whole folder
hlint --report src/an HTML report, report.html

Options

--report
write an HTML report
--hint=FILE
use hints from FILE
-j
use several cores

Notes

  • A suggestion can be switched off for a project in .hlint.yaml: - ignore: {name: "Use camelCase"}.
  • 64-bit only, like GHC.

See also ghc

java OpenJDK 21: run Java programs, and with javac and jshell, write them.

Languages · command-line tool · openjdk21-jre-headless 21.0.12_p8 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs java-common, java-cacerts, zlib

On Copal: The catalogue's Java, on the 64-bit boards: for the programs that ship as a .jar, and for learning or writing Java itself.

Usage: java [options] <mainclass> [args...]
           (to execute a class)
   or  java [options] -jar <jarfile> [args...]
           (to execute a jar file)

Use

java File.java compiles and runs a single-file program at once. javac compiles, java -jar runs a packaged program, and jshell is an interactive prompt.

Examples

java Hello.javacompile and run one file
javac Hello.java && java Hellocompile, then run the class
java -jar program.jara packaged program
jshelltry Java a line at a time; /exit leaves
java -Xmx256m -jar program.jarcap its memory on a small board

Options

-jar FILE
run a packaged program
-cp PATH
where to find classes and jars
-Xmx SIZE
the most heap it may use: -Xmx256m
-version
the version (to stderr)

Notes

  • On a Pi with little memory, -Xmx keeps a program from taking all of it; Java's default is a quarter of RAM.
  • 64-bit only: its catalogue row is gated to aarch64 and x86_64.

See also plantuml

lua5.4 The Lua 5.4 interpreter -- with LuaJIT beside it for speed.

Languages · terminal program · lua5.4 5.4.8 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man lua5.4(1) · home

needs lua5.4-libs, readline

On Copal: The catalogue's Lua: the small language Neovim, many games and configuration files are scripted in. The command carries its version; luajit is the fast 5.1-compatible one.

lua [ options ] [ script [ args ] ]

Use

Run a script, or start the prompt and type. -e runs a line.

Examples

lua5.4the prompt; Ctrl-D leaves
lua5.4 script.luarun a script
lua5.4 -e 'print(2^10)'one line
luajit script.luathe same script, often much faster
lua5.4 -i config.luarun it, then stay at the prompt

Options

-e CODE
run CODE
-i
stay interactive after running a script
-l NAME
require library NAME first
-v
the version

Notes

  • Plain lua may be another version: on a machine where something pulled in Lua 5.1, lua is 5.1. Say lua5.4 to be sure; lua -v tells.
  • LuaJIT implements Lua 5.1, not 5.4: integer division // and some newer features are missing there.
  • Libraries come from Alpine as lua5.4-* packages.

See also nvim, lua-language-server

nim Nim: a compiled language that reads like Python and runs like C.

Languages · command-line tool · nim 2.2.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs libucontext-dev

On Copal: The catalogue's Nim: small, fast programs from code as terse as a script, on every port the Pi runs.

Use

nim c compiles a file through C; -r runs the result. -d:release turns on the optimisations for the version you keep.

Examples

nim c -r hello.nimcompile and run
nim c -d:release -o:hello hello.niman optimised program called hello
nim r hello.nimcompile and run, no binary kept
nim check hello.nimcheck it without building

Options

c / compile
compile to C, then to a program
r
compile and run, leaving no binary behind
-r, --run
run after compiling
-d:release
optimised build
-o:FILE
the output name
check
check the file for errors only

Notes

  • nimble, Nim's package manager, is not installed here; a few libraries come from Alpine as nim-* packages.
  • The build cache is ~/.cache/nim; delete it if builds behave oddly.

See also python3, gcc, crystal

ocaml OCaml: a strict functional language with ML's type inference, and a fast native compiler.

Languages · terminal program · ocaml 4.14.4 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ocaml(1) · home

needs ocaml-runtime, gcc

On Copal: The catalogue's ML on every port, the Zero included: where GHC is not built, OCaml gives the same type system, pattern matching and inference, with a native compiler small enough for the board.

ocaml [ options ] [ object-files ] [ script-file ]

Use

ocaml is the interactive toplevel: type an expression, end it with ;;. ocamlopt compiles to a native program, ocamlc to bytecode.

Examples

ocamlthe toplevel; #quit;; to leave
ocaml script.mlrun a file
ocamlopt -o hello hello.mla native executable
ocamlc -o hello.byte hello.mlbytecode, runs anywhere OCaml does
let square x = x * x;; (at the toplevel) define
List.map square [1; 2; 3];; use: - : int list = [1; 4; 9]

Options

FILE
run it
-I DIR
search DIR for compiled modules
-init FILE
load FILE at start instead of ~/.ocamlinit

Notes

  • This is OCaml 4.14. opam and dune are not installed; libraries come from Alpine as ocaml-* packages (apk search ocaml-).
  • Every toplevel input ends with ;;, or nothing happens.

See also ghc, racket

perl Perl: text processing, one-liners, and a great deal of Unix glue.

Languages · command-line tool · perl 5.42.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man perl(1) · home

needs libbz2, zlib

On Copal: On every Copal machine: much of the system's own tooling is Perl, and its one-liners edit files and reports faster than anything.

perl [ -sTtuUWX ]
        [ -hv ] [ -V[:configvar] ]
        [ -cw ] [ -d[t][:debugger] ] [ -D[number/list] ]
        [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ]
        [ -Idir ] [ -m[-]module ] [ -M[-]'module...' ] [ -f ]
        [ -C [number/list] ]
        [ -S ]
        [ -x[dir] ]
        [ -i[extension] ]
        [ [-e|-E] 'command' ] [ -- ] [ programfile ] [ argument ]...

For more information on these options, you can run "perldoc perlrun".

Use

Run a script, or a one-liner with -e. With -n or -p it loops over every input line; with -i it edits files in place.

Examples

perl -e 'print 2**40, "\n"'one line
perl -ne 'print if /error/i' log.txtgrep, case-insensitive
perl -pi -e 's/colour/color/g' *.mdedit files in place
perl -pi.bak -e 's/foo/bar/' confthe same, keeping conf.bak
perldoc -f sprintfthe manual for one function

Options

-e CODE
run CODE
-n / -p
loop over input lines (-p also prints each)
-i[EXT]
edit in place, keeping a backup with EXT
-l
chomp input lines and add newlines to print
-w
warnings
-M MODULE
use MODULE first

Notes

  • Libraries come from Alpine as perl-* packages: apk search perl-json. cpan is not installed.
  • -i without an extension edits with no backup; give one while learning.

See also awk, sed, python3, ruby

racket Racket: a Scheme descendant built for making languages -- and for teaching.

Languages · terminal program · racket 9.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man racket(1) · home

needs ca-certificates, libcrypto3, libssl3, lz4-libs, libncursesw, zlib

On Copal: The catalogue's Racket, with raco for packages and builds. How to Design Programs is taught in it, and its #lang line makes a file any of many languages.

racket [ option ...  ] [ argument ...  ]

Use

Run a .rkt file, or start the REPL. The first line of a file, #lang racket, says which language it is written in.

Examples

racketthe REPL; ,exit to leave
racket hello.rktrun a file
racket -e '(displayln (* 6 7))'one expression
raco make hello.rktcompile it ahead of time
raco pkg install gregora package

Options

-e EXPR
evaluate EXPR
-i
the REPL, after the other options
-l LIB
require LIB first
-t FILE
require FILE (runs it)

Notes

  • DrRacket, the teaching IDE, is a separate window program; this is the command line.
  • Packages install per user under ~/.local/share/racket.

See also guile, csi, sbcl

retro RetroForth: a small, modern language in the Forth family.

Languages · terminal program · retroforth 2025.08 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man retro(1) · home

On Copal: The catalogue's Forth. Alpine packages no gforth on any architecture; RetroForth is packaged everywhere and actively kept. It is not ANS Forth: the words differ.

retro [-h] [-i] [-v] [-t filename] [-f filename] [-p filename] [-u filename] [-r filename]
      [filename script-args]

Use

Type at the prompt, or run a file. Values go on a stack; words take them off and put results back. A prefix says what a token is: # a number, ' a string, : a new definition.

Examples

retrothe interactive prompt
retro program.retrorun a file
echo "#2 #3 + n:put" | retroprints 5
2 #3 + n:put (at the prompt) add, print the number
'hello s:put print a string
:square dup * ; define a word
7 square n:put use it: 49

Options

-i
interactive mode
-f FILE
run the code blocks in FILE
-h
the usage

Notes

  • Code in a .retro file runs only inside fenced blocks (~~~ lines): the rest is prose, literate-programming style.
  • copal-guide languages says more about why it is Retro, not gforth.

See also guile, lua5.4

ruby The Ruby language: scripts, one-liners, and gems.

Languages · terminal program · ruby 3.4.9 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man ruby(1) · home

needs ca-certificates, gmp, ruby-libs, libucontext, zlib

On Copal: The catalogue's Ruby, with irb for trying things and gem for libraries -- for scripting, and for the tools written in it.

ruby [--copyright] [--version] [-SUacdlnpswvy] [-0[octal]] [-C directory] [-E
external[:internal]] [-F[pattern]] [-I directory] [-K[c]] [-T[level]] [-W[level]] [-e
command] [-i[extension]] [-r library] [-x[directory]] [--{enable|disable}-FEATURE]
[--dump=target] [--verbose] [--crash-report=template] [--] [program_file] [argument ...]

Use

Run a script, or irb to type Ruby interactively. -e runs one line; with -n or -p it runs over every line of input, like awk.

Examples

irbinteractive Ruby; exit to leave
ruby script.rbrun a script
ruby -e 'puts 2**100'one line
ruby -ne 'puts $_ if /error/' log.txtgrep, in Ruby
gem install --user-install rakea gem, in your home

Options

-e CODE
run CODE
-n / -p
loop over input lines (-p also prints them)
-i[EXT]
edit files in place (with -p)
-I DIR
add DIR to the load path
-w
warnings

Notes

  • gem install without --user-install wants to write system directories: use --user-install, or an apk add ruby-NAME package.
  • User gems' commands land in ~/.local/share/gem/ruby/*/bin, which is not on PATH until you add it.

See also python3, perl, crystal

rust-analyzer The Rust language server: completion, types on hover, go-to-definition, inline errors.

Languages · command-line tool · rust-analyzer 2026.06.08 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs rust-src, mimalloc2

On Copal: Stage 7 installs it with Rust, and Neovim and Helix start it for .rs files. It is what makes a Rust project navigable in the editor.

Use

The editor runs it; there is nothing to start by hand. Open a file inside a Cargo project and it indexes the project, then answers the editor.

Examples

rust-analyzer --versionwhich version is installed
rust-analyzer diagnostics .the project's errors, from the shell
which rust-analyzerwhich one the editor will find

Options

diagnostics DIR
print the diagnostics for the project in DIR
--version
the version

Notes

  • It needs the standard library's source: rust-src, which the Rust row installs.
  • With rustup installed, ~/.cargo/bin comes first on PATH and its rust-analyzer is a proxy that says "unavailable for the active toolchain" until rustup component add rust-analyzer.
  • The first index of a large project takes a while and a lot of memory on a small Pi.

See also cargo, nvim, hx

sbcl Steel Bank Common Lisp: a fast, native Common Lisp compiler with an interactive REPL.

Languages · terminal program · sbcl 2.6.5 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man sbcl(1) · home

needs zstd-libs

On Copal: The catalogue's Common Lisp: it compiles every expression to native code as you type it, so the REPL is as fast as a built program.

Use

Start the REPL and type forms, or run a file with --script. Emacs and Neovim plugins can talk to it for a full Lisp environment.

Examples

sbclthe REPL; (quit) to leave
sbcl --script hello.lisprun a file and exit
sbcl --eval '(print (expt 2 100))' --quitone expression
sbcl --load project.lispload a file, then the REPL
(defun square (x) (* x x)) (at the REPL) define
(square 12) => 144

Options

--script FILE
run FILE non-interactively, then exit
--load FILE
load FILE, then continue
--eval FORM
evaluate FORM
--quit
exit after the --load and --eval options
--noinform
no banner

Notes

  • An error drops into the debugger, with numbered restarts: type the number of ABORT (usually 0) to get back to the prompt.
  • Libraries come through Quicklisp, which is installed by loading its quicklisp.lisp from quicklisp.org once.

See also guile, racket, csi

tcc The Tiny C Compiler: compiles C almost instantly, and can run a C file as a script.

Languages · command-line tool · tcc 0.9.27_git20250619 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man tcc(1) · home

needs tcc-libs

On Copal: The catalogue's fastest C compiler: for trying an idea, or running C like a script, on a board where gcc takes its time.

usage: tcc [options] [infile1 infile2...] [-run infile args...]

Use

Compile as with gcc, or tcc -run file.c to compile and run in one go, in memory. It optimises little: for speed of compiling, not of the program.

Examples

tcc -run hello.ccompile and run, no file left behind
tcc -run prog.c arg1 arg2with arguments for the program
tcc -o hello hello.can executable
echo 'int main(){return 42;}' | tcc -run -from stdin

Options

-run
compile and run at once
-o FILE
the output
-c
compile to an object file
-g
debug information
-Wall
warnings
-I DIR
a header directory; -L DIR -lNAME libraries

Notes

  • A file starting #!/usr/bin/tcc -run can be made executable and run directly, like a shell script.
  • It supports C99 and most of C11; code leaning on GCC extensions may not compile.

See also gcc, clang

zig The Zig language and toolchain -- and a C compiler that cross-compiles anywhere.

Languages · command-line tool · zig 0.16.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs llvm21-libs, clang21-libs, lld21-libs

On Copal: The catalogue's Zig, on the 64-bit boards. Beside the language, zig cc compiles C for any target from this machine, a Zero or a Mac included.

Usage: zig [command] [options]
Commands:

Use

zig run compiles and runs a file; zig build-exe makes a program; zig init starts a project that zig build builds.

Examples

zig run hello.zigcompile and run
zig build-exe hello.zig -O ReleaseSmalla small, optimised program
zig init && zig build runa new project, built and run
zig test sum.zigrun a file's tests
zig cc -o hello hello.c -target arm-linux-musleabihfC, for a 32-bit Pi

Options

run FILE
compile and run
build-exe FILE
make an executable
init
start a project here
build
build the project (build.zig)
test FILE
run the tests
fmt FILE
reformat the source
cc
act as a C compiler (with -target for another machine)

Notes

  • The language is not at 1.0: code written for another Zig version may need changes. zig version says which this is.
  • 64-bit only: its catalogue row is gated to aarch64 and x86_64.

See also gcc, clang, go

Learn

gtypist GNU Typist: touch-typing lessons and drills in the terminal.

Learn · terminal program · gtypist 2.10.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man gtypist(1) · home

needs ncurses, perl, libintl, libncursesw

On Copal: The catalogue's typing tutor: lessons from the home row up, with speed and error rates, in any terminal -- the course copal-guide keyboard points to.

gtypist [OPTION]... [SCRIPT]...

Use

Start it and pick a course from the menu: the Q series teaches QWERTY from nothing, others Dvorak, Colemak and numbers. Each lesson explains, then drills; mistakes show as you make them.

Examples

gtypistthe menu of courses
gtypist -btrack your personal best speeds
gtypist -e 3allow up to 3% errors before a repeat
gtypist -nno timer: accuracy only

Options

-b, --personal-best
keep your best speeds
-e, --max-error=PCT
the error rate a drill may have (default 3)
-n, --notimer
turn off the speed timer
-t, --term-cursor
use the terminal's own cursor

Notes

  • Escape leaves a lesson; the menu's last line exits.
  • It comes from Alpine's testing repository (gtypist@testing).

See also copal-morse

Mail

aerc A modern terminal mail client: tabs, vim-style keys, and a setup wizard.

Mail · terminal program · aerc 0.21.0 · stage 12 · The application catalogue · man aerc(1) · home

needs less, ncurses, notmuch-libs

On Copal: The catalogue's newest terminal mail client: it walks you through the account on first start, keeps several mailboxes in tabs, and opens the editor in a terminal inside itself.

aerc [-h] [-v] [-a <name>] [-C <file>] [-A <file>] [-B <file>] [-I] [mailto:<...> |
mbox:<file> | :<command...>]

For a guided tutorial, use :help tutorial from aerc, or man aerc-tutorial from your terminal.

Use

Start it; the first time, a wizard asks for your address and servers and writes the account file. After that it is tabs of mailboxes and messages, with the keys and :commands of vim.

Examples

aercstart; the wizard on first run
aerc mailto:you@example.orgcompose to an address
j k Enter (in aerc) move / open a message
C Rr rr compose / reply / reply to all
:new-account run the wizard for another account
Ctrl-N Ctrl-P next / previous tab; q close a message, or quit

Options

-A FILE
another accounts.conf
-C FILE
another aerc.conf
-v
the version
mailto:URL
start composing to that address

Notes

  • Accounts are in ~/.config/aerc/accounts.conf, passwords included unless a source-cred-cmd fetches them: keep that file private (chmod 600).
  • The keys are its binds.conf; :help keys lists what is bound.
  • HTML mail shows as text only when a filter is configured; the default filters are in aerc.conf's [filters] section.

See also mutt, alpine, vim

alpine The pine mail reader, continued: menus on screen, IMAP and SMTP built in.

Mail · terminal program · alpine 2.26 · stage 12 · The application catalogue · man alpine(1) · home

needs libcrypto3, libldap, libncursesw, libssl3

On Copal: The catalogue's gentlest terminal mail client, and the heir to elm, which Alpine no longer packages. Every key it takes is listed at the foot of the screen.

Use

Set up your account once in Setup, then read, write and file mail with the single-letter commands shown at the bottom of every screen. It talks to an IMAP server for reading and an SMTP server for sending, so the mail stays on the server.

Examples

alpinestart; the main menu
alpine you@example.orgstraight to composing a message
alpine -f INBOXopen a folder directly
alpine -istraight to the message index
S C (in alpine) Setup, then Config: server names, your address
I L the message index / the folder list
C R F compose / reply / forward
Ctrl-X send, from the composer; Q quit

Options

ADDRESS
start composing to ADDRESS
-f FOLDER
open FOLDER
-i
start in the index
-I KEYS
type these keys at start (a script of commands)
-p FILE
use FILE as the configuration instead of ~/.pinerc
-d N
debug level

Notes

  • Server names go in Setup > Config: inbox-path as {imap.example.org/ssl/user=you}INBOX, and smtp-server as smtp.example.org/submit/user=you -- the braces and slashes are alpine's own syntax.
  • The configuration is ~/.pinerc; the Setup screens write it for you.
  • Gmail and most large providers want an app password, not your normal one, for a program like this.

See also mutt, aerc, mail

irssi A terminal IRC client: one window per channel, scriptable in Perl.

Mail · terminal program · irssi 1.4.5 · stage 12 · The application catalogue · man irssi(1) · home

needs libcrypto3, glib, libncursesw, libssl3, utf8proc

On Copal: One of the catalogue's chat clients. IRC is where many free software projects still talk -- Alpine's own channels are on OFTC -- and irssi runs happily in tmux on a machine that stays on.

irssi [--config=PATH] [--home=PATH] [-dv!?] [-c server] [-p port] [-n nickname] [-w password]
[-h hostname]

Use

Start it, connect to a network, join channels. Each channel is a numbered window: Alt and a number, or /window N, switches to it. Run it inside tmux and detach, and you stay in the channels while you are away.

Examples

irssistart
irssi -c irc.oftc.net -n yournickconnect straight to a network
/connect irc.oftc.net (in irssi) connect
/join #alpine-linux join a channel
/msg nick hello a private message
/window 2 or Alt-2 switch window
/quit leave

Options

-c SERVER
connect to SERVER at start
-n NICK
use NICK
-p PORT
the port
--home DIR
another configuration directory

Notes

  • /save writes what you set up to ~/.irssi/config; without it, a network added with /network add is gone next time.
  • Networks increasingly want a registered nick: /msg NickServ help on the network explains its steps.
  • Alt-number may be taken by the terminal or the desktop; /window N always works.

See also weechat, tmux, profanity

mail Send a message from a script, or read local mail, in a line or two.

Mail · command-line tool · mailx 8.1.2_git20220412 · stage 12 · The application catalogue · man mail(1) · home

needs libbsd, liblockfile

On Copal: The catalogue's mail for scripts (mailx), standing in for elm, which Alpine no longer packages. A cron job or a build can mail a result.

mail [-dEIinv] [-a header] [-b bcc-addr] [-c cc-addr] [-r from-addr] [-s subject] [--]
     to-addr ...
mail [-dEIiNnv] -f [file]
mail [-dEIiNnv] [-u user]

Use

Pipe a body into mail -s SUBJECT ADDRESS and it is handed to the system's mail transport. Without arguments it reads the local mailbox, /var/mail/$USER, the way system messages are delivered.

Examples

echo 'Build done' | mail -s 'copal' you@example.orgsend one line
mail -s 'Log' you@example.org < build.loga file as the body
mail -c boss@example.org -s 'Report' you@example.org < r.txtwith a copy
mailread local mail
doas apk add msmtpa way out to real servers

Options

-s SUBJECT
the subject
-c ADDRS
carbon copies
-b ADDRS
blind carbon copies
-f FILE
read FILE as the mailbox
-v
show the delivery's conversation

Notes

  • On Copal nothing is sent until there is a way out. mail hands the message to /usr/sbin/sendmail, which is BusyBox's, and it only forwards to an SMTP server it is told about. Install msmtp, give it your server in ~/.config/msmtp/config, and put set sendmail=/usr/bin/msmtp in ~/.mailrc.
  • This is BSD mail (mailx), not s-nail or Heirloom mailx: the -S smtp= recipes found online are for those, and do not work here.

See also mutt, alpine

mutt A terminal mail reader configured entirely in text: IMAP, SMTP, and every key rebindable.

Mail · terminal program · mutt 2.3.2 · stage 12 · The application catalogue · man mutt(1) · home

needs libcrypto3, gdbm, libgpg-error, gpgme, libgsasl, libidn2, libintl, libncursesw

On Copal: The catalogue's configurable terminal mail client, built here with IMAP, SMTP and TLS, so one config file makes it a complete client.

mutt  [-nRyzZ] [-e command] [-F rcfile] [-m type] [-f mailbox]

mutt  [-Enx] [-e command] [-F rcfile] [-H draft] [-i include]
      [-b bcc-addr] [-c cc-addr] [-s subject]
      [-a file ... --] to-addr ...

mutt  [-nx] [-e command] [-F rcfile] [-b bcc-addr] [-c cc-addr]
      [-s subject] [-a file ... --] to-addr ... < message

mutt  [-n] [-e command] [-F rcfile] -p

mutt  [-n] [-e command] [-F rcfile] -A alias

mutt  [-n] [-e command] [-F rcfile] -Q variable
...

Use

Write a muttrc with your servers, start it, and read mail from an index of messages. Replies and new messages open in your editor ($EDITOR), and are sent when you leave it and confirm.

Examples

muttthe inbox, from the config
mutt -f imaps://you@imap.example.org/an IMAP mailbox without a config
mutt -s 'Report' you@example.org < report.txtsend from a script
mutt -s 'Photos' -a pic.jpg -- you@example.org < note.txtwith an attachment
mutt -vthe version, and what it was built with
j k Enter (in mutt) move / open a message
m r g compose / reply / reply to all
c change to another mailbox; q quit

Options

-f MAILBOX
open MAILBOX: a path, or imaps://user@host/
-s SUBJECT
the subject, when sending from the command line
-a FILE -- TO
attach FILE (the -- ends the attachments)
-F FILE
use FILE as the muttrc
-n
ignore the system configuration
-v
version and build options

Notes

  • The whole configuration is ~/.muttrc (or ~/.config/mutt/muttrc). The minimum: set folder, set spoolfile, set smtp_url and set from, with the servers as imaps:// and smtps:// URLs.
  • This build has IMAP, SMTP and OpenSSL but not SASL, so exotic sign-in methods are out; a password or app password works.
  • Its editor is $EDITOR -- nvim on a Copal machine with stage 7.

See also aerc, alpine, mail, vim

profanity A terminal XMPP (Jabber) chat client, with OMEMO encryption.

Mail · terminal program · profanity 0.18.1 · stage 12 · The application catalogue · man profanity(1) · home

needs libcurl, libgcrypt, glib, libncursesw, libotr, readline, libsignal-protocol-c, sqlite-libs

On Copal: The catalogue's XMPP client: chat on a federated network from a terminal, end to end encrypted, on any machine -- over SSH too.

profanity [-vh] [-l level] [-a account]

Use

Connect with your XMPP address, then chat with contacts or join rooms. Each conversation is a window, switched with Alt and a number. /help lists every command.

Examples

profanitystart
profanity -a you@example.orgconnect as that account at once
/connect you@example.org (in profanity) sign in
/msg friend@example.org open a chat
/join room@conference.example.org join a room
/omemo gen make this device's encryption keys
/quit leave

Options

-a ACCOUNT
connect with a saved account
-l LEVEL
log level
-v
the version

Notes

  • /account add NAME saves an account so -a NAME and /connect NAME work; settings go to ~/.config/profanity/profrc.
  • OMEMO is per device: after /omemo gen, start it in a chat with /omemo start, and trust the other side's fingerprints when asked.

See also irssi, weechat

weechat A terminal chat client for IRC, with a nick list, mouse support and plugins.

Mail · terminal program · weechat 4.9.2 · stage 12 · The application catalogue · man weechat(1) · home

needs cjson, libcurl, libgcrypt, gnutls, libintl, libncursesw, zlib, zstd-libs

On Copal: The catalogue's other IRC client: more on screen than irssi -- a buffer list, a nick list -- and the same life in tmux on a machine that stays on.

weechat [-a|--no-connect] [-d|--dir <path>] [-t|--temp-dir] [-p|--no-plugin] [-P|--plugins <plugins>] [-r|--run-command <command>] [-s|--no-script] [--upgrade] [debug-option...] [plugin:option...]
weechat [-c|--colors]
weechat [-h|--help]
weechat [-l|--license]
weechat [-v|--version]

Use

Add a server once, connect, join channels. Every channel and private conversation is a buffer; Alt with the arrows, or Alt and a number, moves between them.

Examples

weechatstart
/server add oftc irc.oftc.net/6697 -tls (in weechat) add a network
/connect oftc connect to it
/join #alpine-linux join a channel
/buffer 3 or Alt-3 switch buffer
/set irc.server.oftc.autoconnect on connect at every start
/quit leave

Options

-d DIR
another configuration directory
-r COMMAND
run a command after starting
-a
do not connect automatically this time
-v
the version

Notes

  • Settings are saved as they change, in ~/.config/weechat; /save forces it.
  • /fset is the settings browser: search a word and change it in place, instead of hunting through /set.
  • Passwords belong in /secure, which encrypts them, not in plain /set values.

See also irssi, tmux, profanity

Media

alsamixer The sound card's own mixer, in the terminal: every hardware level and switch.

Media · terminal program · alsa-utils 1.2.15.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man alsamixer(1) · home

needs dialog, alsa-ucm-conf, alsa-lib, fftw-single-libs, libformw, libmenuw, libncursesw, libpanelw

On Copal: Stage 10 installs alsa-utils with it. Most volume is PipeWire's (wpctl), but a card's hardware controls -- a headphone switch, a muted input, HDMI -- are set here.

alsamixer [options]

Use

It opens on the default device, which on Copal is PipeWire: one volume. F6 chooses the sound card itself, and shows every control the hardware has. Arrows move and change; M mutes.

Examples

alsamixerthe default device (PipeWire)
alsamixer -c 0the first sound card's own controls
alsamixer -V allplayback and capture together
aplay -lthe cards, and their numbers
F6 (in alsamixer) choose a card
Left Right choose a control; Up Down change it
M mute / unmute (MM at the foot means muted)
F4 the capture (recording) controls; Esc quit

Options

-c N
open card N
-D DEVICE
open a named ALSA device
-V VIEW
playback, capture or all
-g
no colours

Notes

  • "MM" under a control is muted, "00" is playing. A muted Master or Headphone control is the usual reason for silence with the volume up.
  • doas alsactl store keeps hardware levels across reboots; the alsa service restores them at boot.

See also wpctl, pactl

cmus A music player for the terminal: a library, playlists, a queue, and vi-like keys.

Media · terminal program · cmus 2.12.0 · stage 12 · The application catalogue · man cmus(1) · home

needs libflac, alsa-lib, ffmpeg-libavcodec, ffmpeg-libavformat, libelogind, faad2-libs, libmad, libncursesw

On Copal: The catalogue's terminal music player: a whole collection, sorted and searchable, playing in a tmux pane or over SSH on a Pi wired to speakers.

cmus [options]

Use

Add your music folder once, then browse the library by artist and album and play. The number keys switch views; the command line (:) does the rest. It keeps playing when you switch to another view.

Examples

cmusstart
:add ~/Music (in cmus) add a folder to the library
1 2 3 library / sorted list / playlist views
5 the file browser: Enter plays, a adds
x c v play / pause / stop
b z next / previous track
+ - volume; / search; q quit

Options

--listen ADDR
the address cmus-remote controls it at
--plugins
list the input and output plugins
--show-cursor
keep the cursor visible
--help
the short usage

Notes

  • cmus-remote controls a running cmus from another shell or a key binding: cmus-remote -u pauses, -n skips.
  • No sound? :set output_plugin=pulse sends it through PipeWire's pulse layer; alsa goes through PipeWire's ALSA plugin. Both reach the same place.
  • The library and settings are in ~/.config/cmus.

See also ncmpcpp, alsamixer, wpctl

ncmpcpp A terminal client for MPD, the music player that runs in the background.

Media · terminal program · ncmpcpp 0.10.1 · stage 12 · The application catalogue · man ncmpcpp(1) · home

needs boost1.84-filesystem, boost1.84-locale, boost1.84-program_options, boost1.84-thread, libcurl, fftw-double-libs, icu-libs, libmpdclient

On Copal: The catalogue's player-as-a-service: MPD plays, ncmpcpp (or mpc, or a phone app) is only the remote -- quit it and the music goes on. The row installs mpd, mpc and ncmpcpp together.

ncmpcpp [options]

Use

Run MPD as yourself with a small config, tell it where the music is, then use ncmpcpp to browse and queue. MPD must be running first: ncmpcpp connects to it on localhost port 6600.

Examples

mkdir -p ~/.config/mpd ~/.local/state/mpd
printf 'music_directory "~/Music"\ndb_file "~/.local/state/mpd/database"\nstate_file "~/.local/state/mpd/state"\naudio_output {\n type "pipewire"\n name "PipeWire"\n}\n' > ~/.config/mpd/mpd.conf
mpdstart MPD, as you
mpc updatescan ~/Music
ncmpcppbrowse and play
1 2 3 (in ncmpcpp) playlist / file browser / search
Enter Space play / add to the playlist
p > < pause / next / previous
q quit ncmpcpp (MPD keeps playing)

Options

-h HOST
the MPD to connect to (default localhost)
-p PORT
its port (default 6600)
-c FILE
another config
-s SCREEN
start on a screen: playlist, browser, search_engine...

Notes

  • "Connection refused" is MPD not running. The system service (/etc/mpd.conf, user mpd) cannot reach your session's PipeWire; run mpd as yourself, as above, from the session.
  • To start it with the desktop, add exec-once = mpd to ~/.config/hypr/local.conf.
  • mpc is the one-line remote for scripts and keys: mpc toggle, mpc next, mpc volume +5.

See also cmus, wpctl, mpc

Multimedia

pipe-viewer Search and play YouTube from the terminal, through mpv, without a browser.

Multimedia · terminal program · pipe-viewer 0.5.3 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man pipe-viewer(1) · home

needs perl-data-dump, perl-json, perl-libwww, perl-lwp-protocol-https, perl-term-readline-gnu, perl-unicode-linebreak

On Copal: The store's YouTube client: searches, channels and playlists at a prompt, played in mpv -- far lighter than a browser tab on a Pi.

Use

Give it search words; it lists the results, numbered. Type a number to play it in mpv; :n goes to the next page. With -n it plays sound only.

Examples

pipe-viewer alpine linux tutorialsearch, then pick by number
pipe-viewer -n lofiaudio only
pipe-viewer --resolution=720p catscap the video resolution
pipe-viewer -id dQw4w9WgXcQplay one video by its ID
pipe-viewer -sc copalsearch for channels

Options

-n, --novideo
audio only
--resolution=RES
the highest resolution: 1080p, 720p, 480p...
-id, --videoids=IDS
play these video IDs
-sc, --channels
search channels
-sp, --search-pl
search playlists
--player=NAME
mpv (default), vlc
-A, --all
play all the results in order

Notes

  • On a small Pi, --resolution=480p or -n keeps playback smooth: the decoding is the cost, not the download.
  • To keep a video, ytq add URL queues it for download instead.

See also ytq, mpv

Network

bluetoothctl Pair, trust and connect Bluetooth devices, from a prompt or one command at a time.

Network · bluez 5.86 · stage 10 · Wireless, audio, capture and disks · man bluetoothctl(1) · home

needs dbus, dbus-libs, glib, json-c, readline, eudev-libs

On Copal: Stage 10 installs BlueZ and starts its service where there is a controller. Keyboards, mice, controllers and headphones all pair here; there is no graphical pairing tool on Copal.

bluetoothctl [-a capability] [-e] [-m] [-t seconds] [-v] [-h]

Use

Run it for an interactive prompt: power on, scan, pair, trust, connect. Pair once and trust once; after that the device reconnects by itself.

Examples

bluetoothctlthe prompt; then:
power on the controller on
agent on answer pairing requests...
default-agent ...from this prompt
scan on wait for the device's address
pair AA:BB:CC:DD:EE:FF pair (accept the PIN if asked)
trust AA:BB:CC:DD:EE:FF let it reconnect by itself
connect AA:BB:CC:DD:EE:FF connect now
bluetoothctl devicesone command, no prompt: known devices
bluetoothctl --timeout 10 scan onscan for ten seconds, then stop
bluetoothctl remove AA:BB:CC:DD:EE:FFforget a device

Options

power on|off
the controller
scan on|off
look for devices
pair / trust / connect ADDR
the three steps
disconnect ADDR
drop the connection
remove ADDR
forget it altogether
devices
the known devices
info ADDR
one device's state: paired, trusted, connected
--timeout SECS
stop a non-interactive command after SECS

Notes

  • "No default controller available": no Bluetooth hardware, or the service is not running -- rc-service bluetooth status. The first Pi Zero and most VMs have none.
  • Headphones pair and connect, but PipeWire plays to them only with its Bluetooth module, pipewire-spa-bluez. Stage 10 installs it from 24 Sep 2026; on a machine installed before that, doas apk add pipewire-spa-bluez, then log out and in.
  • A device that pairs but will not connect again after a reboot was not trusted. trust ADDR.

See also wpctl, rc-service

curl Fetch or send one URL -- HTTP, HTTPS, FTP and more -- from the command line.

Network · curl 8.22.0 · stage 4 · X.Org, i3, a terminal and a browser · man curl(1) · home

needs libcurl, zlib

On Copal: Every download in Copal's install is curl: Mini vMac's sources, the Hyprland configs, the store's release files, each checked against its sha256. It is also how to test a web server or an API.

curl [options / URLs]

Use

Given a URL, print what is there. Save it with -o or -O, follow redirects with -L, and add -f so a server error is an error, not an HTML page saved under your filename.

Examples

curl https://example.comthe page, to the terminal
curl -fLO https://host/file.tar.gzdownload, under the name in the URL
curl -fL -o out.iso -C - URLresume a download that stopped
curl -I https://example.comthe response headers only
curl -fsSL URL | sha remote install script (read it first)
curl -d 'name=copal' https://host/formPOST form data
curl --json '{"a":1}' https://host/apiPOST JSON, with its headers
curl -s -o /dev/null -w '%{http_code}\n' URLjust the status code

Options

-o FILE
save to FILE
-O
save under the URL's own filename
-L
follow redirects
-f, --fail
exit non-zero on an HTTP error, save nothing
-s -S
silent, but still show errors (-sS)
-C -
continue a partial download where it stopped
-I, --head
headers only
-d DATA
POST DATA
--json DATA
POST JSON, with the Content-Type set
-H 'Name: value'
add a header
-u USER:PASS
log in
-w FORMAT
print details after: %{http_code}, %{size_download}
--retry N
try again on a transient failure

Notes

  • Without -L, a download that redirects -- GitHub release files all do -- saves a tiny redirect page. Without -f, a 404 saves the error page. -fL is the habit.
  • Without -o or -O, a binary goes to the terminal; curl refuses and says so.
  • BusyBox has wget too, with far fewer options; curl is the one the answers online assume.

See also links, rsync, ssh

ip Show and change network interfaces, addresses and routes.

Network · busybox 1.37.0 · Alpine's base system · man busybox(1) · home

a BusyBox applet: busybox ip --help, and BusyBox's page

On Copal: The quickest answer to "what is my address" and "is the wifi up". On Copal it is BusyBox's applet: the common part of iproute2's ip, not all of it.

Use

ip addr shows each interface and its addresses, ip route where traffic goes, ip link whether an interface is up. Changes made with it last until the next restart; the lasting configuration is /etc/network/interfaces.

Examples

ip addrevery interface and its addresses
ip -4 -o addrIPv4 only, one line each
ip addr show wlan0one interface
ip routethe default gateway is the 'default via' line
doas ip link set wlan0 upbring an interface up
ip neighmachines seen on the local network
doas rc-service networking restartre-apply /etc/network/interfaces

Options

addr [show DEV]
addresses (a, address)
route
the routing table (r)
link
interfaces, up or down, and their MAC addresses
neigh
the neighbour (ARP) table
-f inet
one address family: inet, inet6 (-4 and -6 work too)
-o
one line per entry, for grep
link set DEV up
bring DEV up; down to take it down

Notes

  • BusyBox's ip lacks the newer options: ip -br a, -c and -j print its usage instead. Use ip -o addr for the short form.
  • No IPv4 address on wlan0 means it is not associated, or DHCP has not answered: check iw dev wlan0 link before blaming DHCP.
  • ifconfig is here too (BusyBox), for the habit; ip is what Alpine's own scripts use.
  • /etc/network/interfaces is read by ifup and ifdown (ifupdown-ng): auto wlan0 and iface wlan0 inet dhcp make it come up at boot.

See also iw, wpa_cli, ssh, busybox

iw Look at and control wireless interfaces: scan, link, signal, country.

Network · iw 6.17 · stage 10 · Wireless, audio, capture and disks · man iw(8) · home

needs libnl3

On Copal: Stage 10 installs it with wpa_supplicant for the Pi's wifi. It answers what the radio sees and how well it is connected; joining a protected network is wpa_supplicant's job, not iw's.

iw [ OPTIONS ] { help [  command ] | OBJECT COMMAND }


OBJECT := {  dev | phy | reg }


OPTIONS := { --version | --debug }

Use

Name a wireless interface (wlan0) and ask it something: which networks it can hear, what it is connected to and at what signal, which channels the country allows.

Examples

iw devthe wireless interfaces
doas iw dev wlan0 scan | grep SSIDthe networks in range
iw dev wlan0 linkconnected to what, signal, speed
iw dev wlan0 station dumpthe access point's statistics
iw reg getthe regulatory country in force
doas iw reg set GBset it (use your own country)
iw list | lesseverything the chip can do

Options

dev
list wireless interfaces
dev IF scan
scan for networks (root)
dev IF link
the current connection
dev IF station dump
per-station statistics
reg get / reg set CC
read or set the regulatory country
list
the hardware's capabilities
phy
the radios, as distinct from interfaces

Notes

  • A scan needs root: without it, "Operation not permitted (-1)". "Device or resource busy (-16)" means the interface is down -- doas ip link set wlan0 up -- or blocked: rfkill list, then doas rfkill unblock wifi.
  • 5 GHz networks missing from a scan often means no country is set: the radio then allows only what is legal everywhere.
  • iw dev wlan0 connect joins open networks only. For WPA, which is nearly every network, use wpa_supplicant -- setup-interfaces or wpa_cli.
  • The Pi Zero (the first one) has no wifi at all; the Zero W and Zero 2 W do.

See also wpa_cli, wpa_passphrase, ip

ssh Log in to another machine, or run one command on it, over an encrypted connection.

Network · openssh-client-default 10.3_p1 · stage 1 · Apply the setup-alpine answers · man ssh(1) · home

needs openssh-keygen, openssh-client-common, !openssh-client-krb5, libcrypto3, zlib

On Copal: How a Copal machine is reached from the Mac, and how it reaches GitHub and the others. Stage 1 turns on sshd; stage 6 authorises the Mac's key, so the first login needs no password.

ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address] [-c cipher_spec]
    [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
    [-i identity_file] [-J destination] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd]
    [-o option] [-P tag] [-p port] [-R address] [-S ctl_path] [-W host:port]
    [-w local_tun[:remote_tun]] destination [command [argument ...]]
ssh [-Q query_option]

Use

ssh user@host opens a shell there; ssh host command runs one command and returns. The same connection carries files (scp, rsync, sshfs) and ports (-L). A key instead of a password is set up once, with ssh-keygen and ssh-copy-id.

Examples

ssh you@192.168.1.20a shell on another machine
ssh pi 'df -h /'one command, then back
ssh -p 2222 you@example.orgsshd on another port
ssh -L 8080:localhost:80 pithe Pi's port 80 as localhost:8080 here
ssh -J gateway you@insidethrough a machine in between
ssh-copy-id you@192.168.1.20install your key there, once
ssh -v pisay why a connection fails

Options

-p PORT
connect to this port
-i FILE
use this private key
-L L:HOST:R
forward local port L to HOST:R, from the far side
-R R:HOST:L
the reverse: a port there comes back here
-J HOST
jump through HOST first
-N
no command: just hold the forwards open
-t
force a terminal, for an interactive program: ssh -t pi htop
-o KEY=VALUE
any config option, for once
-v
debug output; -vvv for more

Notes

  • ~/.ssh/config saves typing: a Host pi block with HostName, User and Port makes ssh pi enough, and scp, rsync and git use it too.
  • "REMOTE HOST IDENTIFICATION HAS CHANGED" after reinstalling a card is expected: the new system made new host keys. Remove the old one with ssh-keygen -R HOST, then connect again. Anywhere else, stop and ask why.
  • A frozen session (the far side went away) does not answer Ctrl-C. Type Enter, then ~. -- ssh's escape -- and it closes.
  • Password refused although it is right? Copal can turn password logins off: copal-ssh status says what is in force on the machine you are connecting to.

See also ssh-keygen, rsync, tmux, curl

ssh-keygen Make SSH keys, and inspect, fix or forget them.

Network · openssh-keygen 10.3_p1 · stage 1 · Apply the setup-alpine answers · man ssh-keygen(1) · home

needs libcrypto3

On Copal: A key is what lets this machine push to GitHub and log in to the others without a password. Stage 7 tells you to make one when a checkout falls back to HTTPS; stage 16's fleet reads its host certificates with it.

ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile] [-m format]
           [-N new_passphrase] [-O option] [-t ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]
           [-w provider] [-Z cipher]
ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase] [-P old_passphrase]
           [-Z cipher]
ssh-keygen -i [-f input_keyfile] [-m key_format]
ssh-keygen -e [-f input_keyfile] [-m key_format]
ssh-keygen -y [-f input_keyfile]
ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]
ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]
ssh-keygen -B [-f input_keyfile]
ssh-keygen -D pkcs11
ssh-keygen -F hostname [-lv] [-f known_hosts_file]
ssh-keygen -H [-f known_hosts_file]
...

Use

Make a key pair: a private half that stays in ~/.ssh and a .pub half you give away. Beyond that it answers questions about keys -- fingerprints, certificates -- and removes stale hosts from known_hosts.

Examples

ssh-keygen -t ed25519 -C "$(hostname)"a new key (Enter for the defaults)
cat ~/.ssh/id_ed25519.pubthe half to paste into GitHub
ssh-keygen -l -f ~/.ssh/id_ed25519.pubits fingerprint
ssh-keygen -R 192.168.1.20forget a host whose key changed
ssh-keygen -p -f ~/.ssh/id_ed25519add or change the passphrase
ssh-keygen -y -f ~/.ssh/id_ed25519rebuild a lost .pub from the private key

Options

-t TYPE
the key type: ed25519 (use this), rsa, ecdsa
-C COMMENT
a label stored in the key: who and where
-f FILE
the key file to make or read
-N PHRASE
the passphrase, given on the command line ('' for none)
-l
show a key's fingerprint
-R HOST
remove HOST from known_hosts
-F HOST
find HOST in known_hosts
-p
change a key's passphrase
-y
print the public key of a private one
-L
show a certificate's contents

Notes

  • The private file (id_ed25519, no .pub) never leaves the machine. If it is ever pasted anywhere, make a new pair.
  • ssh refuses a private key others can read: "UNPROTECTED PRIVATE KEY FILE". chmod 600 ~/.ssh/id_ed25519 and chmod 700 ~/.ssh.
  • Use ed25519: short, fast, and accepted everywhere Copal connects to. Only very old servers need -t rsa -b 4096.
  • Running it again over an existing key asks before overwriting -- say no unless you mean to replace the key everywhere it is installed.

See also ssh, git

wpa_cli Talk to the running wpa_supplicant: scan, add a network, see the state.

Network · wpa_supplicant 2.11 · stage 10 · Wireless, audio, capture and disks · man wpa_cli(8) · home

needs libcrypto3, dbus-libs, libnl3, pcsc-lite-libs, libssl3

On Copal: Copal's wifi is wpa_supplicant (stage 10), not NetworkManager, so there is no nmcli. wpa_cli is how to join a new network or see why one will not connect, without editing files and restarting.

wpa_cli [ -p path to ctrl sockets ] [ -g path to global ctrl_interface socket ] [ -i ifname ]
[ -hvB ] [ -a action file ] [ -P pid file ] [ -G ping interval ] [ command ... ]

Use

With a command, run it and return; with none, an interactive prompt where the same commands work, with tab completion and live events. Add a network, set its name and password, enable it, and save.

Examples

wpa_cli -i wlan0 statusconnected? to what, with which address
wpa_cli -i wlan0 scanstart a scan...
wpa_cli -i wlan0 scan_results...and read it
wpa_cli -i wlan0 list_networksthe networks it knows
wpa_cli -i wlan0 add_networka new one: prints its number, say 1
wpa_cli -i wlan0 set_network 1 ssid '"Home WiFi"'
wpa_cli -i wlan0 set_network 1 psk '"the password"'
wpa_cli -i wlan0 enable_network 1try it
wpa_cli -i wlan0 save_configkeep it across reboots

Options

-i IF
the interface, wlan0
-p DIR
where the control sockets are (/run/wpa_supplicant)
status
state, SSID, address
scan, scan_results
scan, then list what was found
list_networks
the configured networks and their numbers
add_network
a new empty network; prints its number
set_network N KEY VALUE
ssid, psk, key_mgmt, priority...
enable_network N
allow it; select_network N uses only it
remove_network N
forget it
save_config
write the configuration file
reconfigure
re-read the configuration file

Notes

  • "Failed to connect to non-global ctrl_ifname": wpa_supplicant has no control socket. The file setup-interfaces writes has no ctrl_interface line; add ctrl_interface=DIR=/run/wpa_supplicant GROUP=wheel and update_config=1 at the top of /etc/wpa_supplicant/wpa_supplicant.conf, then doas rc-service wpa_supplicant restart.
  • The quotes are both needed: '"Home WiFi"'. The outer pair is for the shell; the inner pair tells wpa_supplicant it is text, not hex.
  • save_config fails without update_config=1 in the file, and the network is forgotten at the next restart.
  • The password typed into set_network lands in the shell's history. wpa_passphrase avoids that.

See also wpa_passphrase, iw, ip

wpa_passphrase Turn a wifi name and password into a network block for wpa_supplicant.

Network · wpa_supplicant 2.11 · stage 10 · Wireless, audio, capture and disks · man wpa_passphrase(8) · home

needs libcrypto3, dbus-libs, libnl3, pcsc-lite-libs, libssl3

On Copal: Alpine's own setup-interfaces uses it to write Copal's wifi configuration, and it is the quick way to add a second network by hand without leaving the password in the file as plain text.

wpa_passphrase [ ssid ] [ passphrase ]

Use

Give it the network's name; type the password when it asks. It prints a network={...} block with the password hashed into a 64-digit psk, ready to add to /etc/wpa_supplicant/wpa_supplicant.conf.

Examples

wpa_passphrase "Home WiFi"type the password; prints the block
wpa_passphrase "Home WiFi" | doas tee -a /etc/wpa_supplicant/wpa_supplicant.conf
doas rc-service wpa_supplicant restartuse the new network
wpa_passphrase "Home WiFi" 'the password'password as an argument (see Notes)

Options

SSID
the network's name; quote it if it has spaces
PASSPHRASE
the password, 8 to 63 characters; omit it to be asked

Notes

  • The block it prints includes the password in clear, as a comment (#psk="..."). Delete that line from the file -- setup-interfaces does the same.
  • A password on the command line is saved in the shell's history. Leave it off and type it at the prompt instead; piping it in does not work ("Not a tty").
  • The hash depends on the name: rename the network and the psk must be made again.
  • Open networks and WPA3-only networks need a block written by hand (key_mgmt=NONE, or key_mgmt=SAE with sae_password).

See also wpa_cli, iw, setup-alpine

News

newsboat An RSS and Atom feed reader for the terminal.

News · terminal program · newsboat 2.43 · stage 12 · The application catalogue · man newsboat(1) · home

needs libcurl, libintl, json-c, libncursesw, sqlite-libs, stfl, libxml2

On Copal: The catalogue's terminal feed reader: every site and channel you follow, in one list of unread items, readable over SSH.

newsboat [-r] [-e] [-i opmlfile] [-u urlfile] [-c cachefile] [-C configfile] [-X] [-o] [-x
command...] [-h]

Use

List your feeds' addresses in a file, one per line; newsboat fetches them and shows what is new. Read an item in place, or open it in a browser with o.

Examples

mkdir -p ~/.config/newsboat
echo 'https://alpinelinux.org/atom.xml' >> ~/.config/newsboat/urlsa feed
newsboatread
newsboat -rrefresh every feed at start
newsboat -i subscriptions.opmlimport another reader's list
newsboat -e > feeds.opmlexport yours
newsboat -x reloadrefresh from a script (cron), no screen
R r (in newsboat) reload all / this feed
Enter o read the item / open it in the browser
n the next unread item; A mark the feed read
q back, or quit

Options

-r
refresh all feeds at start
-i FILE
import an OPML file
-e
export the feeds as OPML
-x COMMAND
run reload or print-unread, without the interface
-u FILE
another urls file
-C FILE
another config file

Notes

  • The files are ~/.newsboat/urls and ~/.newsboat/config -- or, if ~/.newsboat does not exist, the same names in ~/.config/newsboat.
  • A YouTube channel is a feed too: https://www.youtube.com/feeds/videos.xml?channel_id=ID.
  • o opens $BROWSER; set browser in the config to a text browser, such as links %u, for use over SSH.

See also newsraft, sfeed, links

newsraft A small, fast feed reader for the terminal, with feeds grouped in sections.

News · terminal program · newsraft 0.37 · stage 12 · The application catalogue · man newsraft(1) · home

needs libcurl, libexpat, gumbo-parser, sqlite-libs

On Copal: The catalogue's lighter feed reader: newsboat's job in less memory, with sections to update and read feeds in groups.

newsraft [-f FILE1] [-c FILE2] [-d FILE3] [-l FILE4] [-e ACTION] [-v] [-h]

Use

Write a feeds file -- a URL a line, with @ Section lines to group them -- and start it. Four menus: sections, feeds, items, and the pager for reading one.

Examples

mkdir -p ~/.config/newsraft
printf '@ Linux\nhttps://alpinelinux.org/atom.xml\n' >> ~/.config/newsraft/feeds
newsraftread
newsraft -e reload-allrefresh everything, no screen (for cron)
newsraft -e convert-opml-to-feeds < subs.opml >> ~/.config/newsraft/feeds
R r (in newsraft) update all / this feed
Enter open; o open the link in a browser
q back, or quit

Options

-f FILE
another feeds file
-c FILE
another config file
-e ACTION
run ACTION and exit: reload-all, convert-opml-to-feeds, convert-feeds-to-opml
-l FILE
write a log to FILE (to see why a feed fails)

Notes

  • The feeds file is ~/.config/newsraft/feeds; nothing starts until it exists.
  • A feed that will not update: newsraft -l log.txt, then look in the log for the HTTP answer.

See also newsboat, sfeed

sfeed Feeds as plain files: fetch with sfeed_update, read with sfeed_curses or plain text.

News · command-line tool · sfeed 2.4 · stage 12 · The application catalogue · man sfeed(1) · home

needs libncursesw

On Copal: The catalogue's feed reader for people who want the feeds as files: one tab-separated line per item, readable with grep, a script or its own small curses reader.

sfeed [baseurl]

Use

List feeds in ~/.sfeed/sfeedrc, run sfeed_update to fetch them into ~/.sfeed/feeds/, and read them with sfeed_curses, or turn them into text, HTML or Atom with the other sfeed_* programs. sfeed itself is the parser in the middle: RSS or Atom in, lines out.

Examples

mkdir -p ~/.sfeed && cp /usr/share/doc/sfeed/sfeedrc.example ~/.sfeed/sfeedrca starting config
sfeed_updatefetch every feed
sfeed_curses ~/.sfeed/feeds/*read them
sfeed_plain ~/.sfeed/feeds/* | headnewest items as plain lines
curl -s https://alpinelinux.org/atom.xml | sfeed | cut -f2the parser alone: titles

Options

sfeed_update [RC]
fetch the feeds listed in RC (default ~/.sfeed/sfeedrc)
sfeed_curses FILES
the reader
sfeed_plain FILES
items as text
sfeed_html FILES
items as an HTML page
sfeed_opml_import
OPML in, sfeedrc lines out

Notes

  • sfeedrc is a shell script: each feed is a line feed 'name' 'https://...' inside the feeds() function.
  • The line format is fixed: time, title, link, content, and more, separated by tabs -- cut -f and awk -F'\t' read it directly.

See also newsboat, newsraft

ticker Live stock and crypto prices in the terminal, with your holdings' gains and losses.

News · terminal program · ticker 5.3.0 · stage 12 · The application catalogue · home

On Copal: The catalogue's market watch: a small full-screen table of prices that updates itself, for a spare terminal or a tmux pane.

Use

Give it the symbols to watch, or keep them -- and what you hold -- in a config file. It refreshes on its own; q quits.

Examples

ticker -w AAPL,MSFT,BTC-USDwatch these
ticker -w AAPL -i 10refresh every 10 seconds
ticker --show-summary --show-holdingswith the config's positions
ticker printholdings once, as text, and exit

Options

-w, --watchlist LIST
symbols to watch, comma-separated
-i, --interval SECONDS
refresh period
--config FILE
the config (default ~/.ticker.yaml)
--show-summary
total gain and loss for your positions
--show-holdings
cost, quantity and weight per position
--show-fundamentals
open, high, low and volume
--sort alpha|value
the order of the list

Notes

  • Symbols are Yahoo Finance's: BTC-USD for Bitcoin, ^GSPC for the S&P 500, a suffix for other exchanges (VOD.L in London).
  • Quotes are delayed by the exchange -- --show-tags says by how much.
  • It comes from Alpine's testing repository (ticker@testing).

See also tmux

Notes

aspell GNU's spell checker: interactive checking of files, and good suggestions.

Notes · command-line tool · aspell 0.60.8.2 · stage 12 · The application catalogue · man aspell(1) · home

needs aspell-libs, libintl, libncursesw

On Copal: The catalogue's other spell checker. Its suggestions for badly mangled words are often better than hunspell's, and it knows the markup of Markdown, HTML and TeX.

aspell [options] <command>

Use

aspell check FILE walks through the file, offering replacements for each unknown word; aspell list prints the unknown words for a script.

Examples

aspell check letter.txtinteractive, with suggestions
aspell -d en_GB check letter.txtBritish spelling
aspell --mode=markdown check README.mdskip code and links
aspell list < letter.txt | sort -uthe misspelled words, once each
aspell dictsthe dictionaries installed

Options

check FILE
check interactively
list
read stdin, print the misspelled words
-d DICT
the dictionary: en, en_US, en_GB, en_CA, en_AU
--mode=MODE
the markup to skip: markdown, html, tex, email
dicts
list the installed dictionaries

Notes

  • check rewrites the file in place and leaves a .bak beside it.
  • English in several spellings is installed (aspell-en); other languages are aspell-de, aspell-fr and so on.
  • Your added words are in ~/.aspell.en.pws.

See also hunspell, vim

hugo A static site generator: Markdown and templates in, a whole website out, fast.

Notes · command-line tool · hugo 0.160.1 · stage 12 · The application catalogue · man hugo(1) · home

On Copal: The catalogue's site builder for a blog, a wiki or a project page: one binary, no runtime, and a site of thousands of pages in seconds.

hugo [flags]

Use

Make a site, add a theme, write content as Markdown under content/, and preview with hugo server. hugo alone builds the finished site into public/.

Examples

hugo new site mysite && cd mysitea new site
hugo new content posts/first.mda page, as a draft
hugo server -Dpreview at localhost:1313, drafts included
hugobuild into ./public
hugo --minifysmaller output

Options

new site DIR
create a site
new content PATH
create a page from its archetype
server
serve and rebuild on change; -D includes drafts
-D, --buildDrafts
include drafts
--minify
minify the HTML, CSS and JS
-d, --destination DIR
build somewhere other than public/

Notes

  • A new site has no theme, and builds blank pages: add one under themes/ and name it in hugo.toml (theme = "name").
  • Pages made with hugo new start as drafts (draft = true) and are left out of a build until that line changes, or -D is given.

See also zola, mdbook

hunspell The spell checker behind LibreOffice and Firefox, from the command line.

Notes · command-line tool · hunspell 1.7.3 · stage 12 · The application catalogue · man hunspell(1) · home

needs libhunspell, libintl, libncursesw, readline

On Copal: The catalogue's spell checker for files and pipes, with American English installed. Programs that check spelling as you type use the same dictionaries.

hunspell [-1aDGHhLlmnOrstvwX] [--check-url] [--check-apostrophe] [-d dict[,dict2,...]]
[--help] [-i enc] [-p dict] [-vv] [--version]
[text/OpenDocument/TeX/LaTeX/HTML/SGML/XML/nroff/troff file(s)]

Use

Check a file interactively, with suggestions for each unknown word, or list the misspelled words for a script. -d chooses the dictionary.

Examples

hunspell letter.txtcheck it, word by word, with suggestions
hunspell -l letter.txtjust the misspelled words
hunspell -l letter.txt | sort -ueach once
echo 'recieve' | hunspell -athe pipe protocol: suggestions for a word
hunspell -D </dev/nullwhich dictionaries are installed

Options

-d DICT
the dictionary: en_US, or another installed one
-l
list misspelled words only
-a
ispell pipe mode, for programs
-H
the input is HTML
-t
the input is TeX
-p FILE
your personal word list

Notes

  • Only en_US is installed. Other languages are packages: apk search hunspell- lists them (hunspell-en-gb, hunspell-de-de...).
  • Words you accept go into ~/.hunspell_en_US (per dictionary); edit it to take one back.

See also aspell, vim

mdbook Write a book as Markdown files and build it into a website.

Notes · command-line tool · mdbook 0.5.3 · stage 12 · The application catalogue · home

On Copal: The catalogue's tool for long-form documentation -- the Rust book is made with it. A folder of Markdown and a table of contents become a searchable site that works offline.

Usage: mdbook [COMMAND]
Commands:
  init         Creates the boilerplate structure and files for a new book

Use

mdbook init makes the skeleton: book.toml and src/, with src/SUMMARY.md as the table of contents. Write chapters as Markdown, list them in the summary, and mdbook serve shows the book in a browser, rebuilding as you save.

Examples

mdbook init mybooka new book, in ./mybook
cd mybook && mdbook serve --openwrite, with a live preview
mdbook buildthe site, into ./book
mdbook cleanremove the built site

Options

init [DIR]
create a book
build
build it, into book/
serve [--open]
serve on localhost:3000, rebuild on change; open the browser
watch
rebuild on change, no server
clean
delete the build

Notes

  • A chapter that is not listed in src/SUMMARY.md is not in the book. Adding a line there that names a missing file creates the file.
  • The built book/ folder is the whole site: copy it to any web server, or open book/index.html from disk.

See also hugo, zola, nvim

vim The Vim editor: modal editing, everywhere, with spell checking.

Notes · terminal program · vim 9.2.1091 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man vim(1) · home

needs vim-common, xxd, libncursesw

On Copal: Stage 7 writes ~/.vimrc -- the half of Copal's editor setup vim and Neovim share: building with F5, the error list, the debugger. The catalogue row adds it with spelling for writing prose.

vim [options] [file ..]
vim [options] -
vim [options] -t tag
vim [options] -q [errorfile]

ex
view
gvim gview evim eview
rvim rview rgvim rgview

Use

Edit text with Vim's modes: normal mode to move and change, insert mode to type. On Copal, nvim is the full IDE; vim is the same editing with fewer parts, and the spell checker is where it earns its row.

Examples

vim notes.mdedit
vim -c 'set spell spelllang=en_us' letter.txtwith spelling on
doas apk add vim-tutor && vimtutorthe half-hour lesson (a separate package)
:set spell (in vim) spell checking on (spelllang=en_gb for British)
]s [s next / previous misspelling
z= suggestions for the word under the cursor
zg add the word to your own list
:w :q :wq write / quit / both

Options

-c CMD
run an Ex command after opening the file
+N
open at line N
-d A B
diff two files
-R
read-only
-u NONE
start with no configuration (to test a problem)

Notes

  • Vim uses its own spell files, not Hunspell's dictionaries. English ships with it; for another language, :set spelllang=de offers to download that file.
  • ~/.vimrc is rewritten when stage 7 runs; your own settings go in ~/.vimrc.local, which it reads last.
  • Words added with zg are kept in ~/.vim/spell/.

See also nvim, hunspell, aspell

zola A static site generator with everything built in: templates, Sass, search, link checking.

Notes · command-line tool · zola 0.22.1 · stage 12 · The application catalogue · home

needs oniguruma

On Copal: The catalogue's other site builder: one binary like Hugo, with a simpler template language, and zola check to find dead links.

Usage: zola [OPTIONS] <COMMAND>
Commands:
  init        Create a new Zola project

Use

zola init asks a few questions and makes the site; pages are Markdown under content/, templates are Tera under templates/. zola serve previews with live reload; zola build writes public/.

Examples

zola init mysite && cd mysitea new site, a few questions
zola servepreview at 127.0.0.1:1111
zola buildbuild into ./public
zola checkbuild without writing, and check every link

Options

init DIR
create a site
serve
serve and rebuild on change
build
build into public/
check
check the site and its links
-r, --root DIR
the site's directory
-c, --config F
another config file

Notes

  • A new site has no templates: pages 404 until there is a templates/index.html, or a theme under themes/ named in config.toml.
  • zola serve listens on localhost only; zola serve -i 0.0.0.0 to preview from another machine.

See also hugo, mdbook

Packages

apk Alpine's package manager: install, remove, upgrade and ask about packages.

Packages · apk-tools 3.0.8 · Alpine's base system · man apk(8) · home

needs libcrypto3, libapk, ca-certificates-bundle, zlib

On Copal: Every program on a Copal machine arrives through it -- the stages call it hundreds of times, and Copal Apps runs it for you. This is apk-tools 3: some answers online are for version 2.

apk [<global options>...] command [<options>...] [<arguments>...]

Use

Keep /etc/apk/world -- the list of packages you asked for -- and make the system match it. apk add and apk del edit that list and then install or remove whatever it now implies; everything else asks questions.

Examples

doas apk updatefetch the current package lists
doas apk upgrade --availableupgrade everything, the usual way
doas apk add ripgrepinstall, and record it in world
doas apk del ripgrepremove it and what only it needed
apk search -e ripgrepis there a package by that exact name
apk info -W /usr/bin/rgwhich package owns this file
apk info -R rsyncwhat a package depends on
doas apk add -t .build gcc makea named group, removed in one step later

Options

add NAME...
install and add to world; NAME@testing for edge/testing
del NAME...
remove from world, and what nothing else needs
update
refresh the package lists (-U does it before any command)
upgrade
install available upgrades
fix NAME
reinstall a package without touching world
info -W FILE
which package owns a file (--who-owns)
info -R / -r NAME
its dependencies / what depends on it
list --installed
what is installed; --upgradable, --orphaned
policy NAME
which repositories carry it, at which versions
-t NAME
with add: a virtual package, so the group is one name
-s
simulate: show what would change, change nothing
--no-cache
use no local cache (apk 3 spells every --no-X this way)

Notes

  • world is the truth. A package installed as a dependency is removed when nothing in world needs it any more; to keep it, apk add it by name.
  • @testing names a repository tag: apk add foo@testing works only when /etc/apk/repositories has a line beginning @testing. Copal adds it the first time a catalogue row asks. One untagged testing name in a list makes apk refuse the whole list.
  • -t groups build dependencies: apk add -t .build gcc make, then apk del .build takes them all away. Copal Apps does exactly this with .copal-store-build-*.
  • On a diskless system (before stage 3) a change survives a reboot only after lbu commit; Copal's installed system is not diskless.

See also doas, flatpak, lbu

flatpak Install and run desktop applications from Flathub, in their own runtime.

Packages · flatpak 1.16.6 · stage 4 · X.Org, i3, a terminal and a browser · man flatpak(1) · home

needs bubblewrap, desktop-file-utils, fuse3, gtk-update-icon-cache, shared-mime-info, xdg-dbus-proxy, libxau, appstream

On Copal: For the few programs Alpine does not package -- a browser like Brave. Copal Apps installs a row marked @flathub through it, and says the cost first: a Flatpak brings its own glibc runtime, about 500 MB, beside the musl system.

flatpak [OPTION...] {COMMAND}

Use

Search Flathub, install an application by its ID, run it. Copal's installation is system-wide (/var/lib/flatpak), so installing and updating need doas; running does not.

Examples

flatpak search bravefind an app's ID
doas flatpak install flathub com.brave.Browserinstall it
flatpak run com.brave.Browserrun it (the menus do this for you)
flatpak list --appinstalled applications
doas flatpak updateupdate apps and runtimes
doas flatpak uninstall --unusedremove runtimes nothing uses
flatpak override --user --filesystem=~/Music com.example.Applet it see a folder

Options

install REMOTE ID
install an application (and its runtime)
uninstall ID
remove it; --unused for orphaned runtimes, --delete-data for its files
update
update everything installed
list --app
applications only; --runtime for runtimes
run ID
start an application
remotes
the configured repositories (Copal adds flathub)
override
change an app's permissions; --show to see them
-y, --assumeyes
answer yes to every question

Notes

  • Space is the cost. The first app brings a runtime of about 500 MB; apps that share it cost only themselves. flatpak list --runtime shows what is installed, uninstall --unused clears what is left over.
  • Flathub builds for 64-bit ARM and x86 only: on a 32-bit Pi there is nothing to install.
  • An app sees only what its permissions allow. A file dialog that cannot find your folder is the sandbox: flatpak override widens it.
  • Prefer the apk when there is one. It is smaller, updates with the system, and is built for musl.

See also apk

Programming

arduino-cli The Arduino toolchain without the IDE: install board cores, compile sketches, upload them.

Programming · command-line tool · arduino-cli 1.5.1 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

On Copal: The store's Arduino: the IDE is Electron and Java and does not run here, but everything it does underneath is this command -- boards, libraries, compile, upload, serial monitor.

Usage:
  arduino-cli [command]
Examples:

Use

Install the core for your board once, then compile and upload a sketch folder. The board is named by its FQBN, such as arduino:avr:uno; board list shows what is plugged in and its port.

Examples

arduino-cli core update-index && arduino-cli core install arduino:avronce, for Uno and Nano
arduino-cli board listthe boards plugged in, and their ports
arduino-cli sketch new Blinka new sketch folder
arduino-cli compile -b arduino:avr:uno Blink
arduino-cli upload -b arduino:avr:uno -p /dev/ttyACM0 Blink
arduino-cli monitor -p /dev/ttyACM0 -c baudrate=9600the serial monitor

Options

core install CORE
install a board platform (arduino:avr, esp32:esp32...)
board list
connected boards and their ports
compile -b FQBN DIR
compile a sketch
upload -b FQBN -p PORT DIR
upload it
lib install NAME
install a library
monitor -p PORT
the serial monitor
config init
write a configuration file to edit

Notes

  • Uploading uses the serial port, which belongs to dialout; Copal adds you with it (copal-store access), then log in again.
  • Other boards' cores need their URL first: arduino-cli config add board_manager.additional_urls URL, then core update-index.
  • It comes from Alpine's testing repository (arduino-cli@testing).

See also screen, make

gh GitHub from the command line: pull requests, issues, releases, repositories and CI runs.

Programming · command-line tool · github-cli 2.97.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man gh(1) · home

needs git

On Copal: The store's GitHub client: everything around the code -- review, issues, Actions -- without a browser, next to git in the same terminal.

gh <command> <subcommand> [flags]

Use

Sign in once with gh auth login; then run commands inside a checkout and gh knows which repository you mean.

Examples

gh auth loginsign in (a browser code, or a token)
gh repo clone owner/projectclone
gh pr listopen pull requests here
gh pr create --filla pull request from this branch
gh pr checkout 42check out someone's pull request
gh issue list --label bugissues with a label
gh run watchfollow the current Actions run

Options

auth login
sign in to GitHub
repo clone R
clone a repository
pr list/create/checkout/merge
pull requests
issue list/create/view
issues
release create TAG
a release, with files
run list/watch
GitHub Actions runs
gist create FILE
a gist

Notes

  • gh auth login can make git use gh for HTTPS as well, so pushes over HTTPS work without a separate token; SSH keys keep working as before.
  • On a machine without a desktop browser, choose the device-code way to sign in: it prints a code to enter on any other device.

See also git, ssh-keygen

node Node.js: run JavaScript outside the browser, with npm for its packages.

Programming · terminal program · nodejs 24.18.1 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · on the Copal Apps shelf · man node(1) · home

needs ca-certificates, ada-libs, brotli-libs, c-ares, libcrypto3, icu-libs, nghttp2-libs, simdjson

On Copal: On Copal because Claude Code runs on it (stage 7 installs it when Claude Code is chosen) and because a checkout builds with npm; the store offers it for JavaScript work of your own.

node [options] [v8-options] [-e string | script.js | -] [--] [arguments ...]
node inspect [-e string | script.js | - | <host>:<port>] ...
node [--v8-options]

Use

Run a script, or start the prompt and type JavaScript. npm installs a project's packages into its node_modules; npm install -g puts tools in your own prefix, ~/.npm-global, which is on PATH.

Examples

nodethe prompt; .exit to leave
node app.jsrun a script
node -e 'console.log(2 ** 53)'one line
node --watch server.jsrestart when the file changes
npm init -y && npm install expressa project and a package
npm install -g prettiera tool, into ~/.npm-global

Options

-e, --eval CODE
run CODE
-p, --print CODE
run CODE and print the result
-c, --check
check the syntax only
-i
the prompt, even when stdin is not a terminal
--watch
restart on changes
--test
run the tests in the project

Notes

  • npm install -g never needs doas here: Copal sets npm's global prefix to ~/.npm-global for your account (/etc/profile.d/npm-global.sh).
  • Packages with native parts compile on install and need build-base and python3; a package shipping glibc binaries will not run on musl.

See also npm, python3

Radio

direwolf A software packet-radio modem and TNC: decode and send AX.25 and APRS through a sound card.

Radio · command-line tool · direwolf 1.8.1 · stage 12 · The application catalogue · man direwolf(1) · home

needs alsa-lib, avahi-libs, libgpiod, gpsd, hamlib, eudev-libs

On Copal: The catalogue's packet radio: with a radio and a sound card, or an RTL-SDR, it decodes APRS position reports and packet messages, and serves them to other programs.

direwolf [ options ] [ - | udp:9999 ]

The first audio channel can be streamed thru stdin or a UDP port.  This is typically used
with an SDR receiver.

Use

It reads audio -- from a sound card, or piped from rtl_fm -- and prints each packet it decodes. A configuration file sets the sound device, the modem speed and your call sign.

Examples

cp /usr/share/doc/direwolf/conf/direwolf.conf ~/a configuration to edit
direwolf -c ~/direwolf.confrun with it
rtl_fm -f 144.39M -s 24000 - | direwolf -r 24000 -D 1 -APRS (N. America) from a dongle
rtl_fm -f 144.8M -s 24000 - | direwolf -r 24000 -D 1 -APRS in Europe

Options

-c FILE
the configuration file
-r RATE
the audio sample rate
-n N
audio channels, 1 or 2
-B RATE
the modem speed: 300, 1200, 9600...
-D N
divide the audio sample rate (with rtl_fm)
-l DIR
write logs of received packets to DIR
-
read audio from stdin

Notes

  • Receiving needs no licence. Transmitting -- beaconing, messaging -- needs an amateur radio licence and your call sign in the configuration.
  • Other programs connect to its KISS and AGW ports (8001 and 8000) for maps and messaging.

See also rtl_test, rigctl

dump1090 Decode aircraft transponder broadcasts (ADS-B, 1090 MHz) from an RTL-SDR.

Radio · command-line tool · dump1090 11.0 · stage 12 · The application catalogue · home

needs bladerf-libs, libncursesw, librtlsdr

On Copal: The catalogue's plane tracker: a dongle and a 1090 MHz antenna show the aircraft overhead -- call sign, altitude, speed, position. This is FlightAware's dump1090-fa.

Use

Run it with the dongle attached; it prints each message it decodes. With --net it serves the data to other programs; with --write-json it writes files a web map can read.

Examples

dump1090decode and print, from dongle 0
dump1090 --net --quietserve on the usual ports, print nothing
dump1090 --write-json /tmp/adsb --quietaircraft.json for a map
dump1090 --gain 40 --lat 51.5 --lon -0.1set gain and your position

Options

--net
serve data on ports 30001-30005
--net-only
network only, no dongle
--write-json DIR
write aircraft.json and friends into DIR
--gain DB
tuner gain
--freq HZ
another frequency (default 1090 MHz)
--lat / --lon
your position, for surface positions and range
--quiet
print nothing to the terminal
--metric
metres and km/h

Notes

  • This build has no --interactive table; for a live view, --write-json and a map page, or another program reading --net's port 30003.
  • A 1090 MHz antenna matters more than anything else: the dongle's own whip hears aircraft a few kilometres away, a tuned one hundreds.
  • The dongle needs plugdev and the TV driver kept off it, as for rtl_test.

See also rtl_test

hackrf_info Identify a HackRF One: its serial number, firmware and board -- and, with its siblings, use it.

Radio · command-line tool · hackrf 2026.01.3 · stage 12 · The application catalogue · home

needs fftw-single-libs, hackrf-libs

On Copal: The catalogue's HackRF tools, for the transmit-and-receive SDR that covers 1 MHz to 6 GHz. hackrf_info is the first check that the board is seen and its firmware matches the tools.

Use

Plug the board in and run it; it prints each board found. The package's other commands record and play samples (hackrf_transfer), sweep the spectrum (hackrf_sweep) and update firmware.

Examples

hackrf_infothe boards found, their firmware
hackrf_transfer -r capture.iq -f 433920000 -s 8000000 -n 80000000ten seconds of samples
hackrf_sweep -f 2400:2500 -l 32 -g 20 > wifi.csvsweep 2.4 GHz

Options

Notes

  • "No HackRF boards found": unplugged, or no permission -- the device belongs to plugdev, which Copal adds you to from 24 Sep 2026.
  • The firmware and the tools should match: a mismatch is reported here, and hackrf-firmware (an optional) carries the matching images.
  • Transmitting needs a licence for the band, and never on frequencies you are not permitted to use.

See also rtl_test, gqrx

rigctl Hamlib's radio control: read and set a transceiver's frequency, mode and more, over its serial port.

Radio · command-line tool · hamlib 4.7.1 · stage 12 · The application catalogue · man rigctl(1) · home

needs libusb

On Copal: The catalogue's rig control: one command for hundreds of radio models, and the library that logging and digital-mode programs use to steer the radio.

rigctl [-hiIlLnouV] [-m id] [-r device] [-p device] [-d device] [-P type] [-D type] [-s baud]
       [-c id] [-t char] [-C parm=val] -Y [-v[-Z]] [command|-]

Use

Name the radio's model number and its port, then give commands: f to read the frequency, F to set it, m / M for the mode. With no commands it opens a prompt.

Examples

rigctl -l | grep -i icomfind your radio's model number
rigctl -m 1 ftry it with model 1, the dummy radio
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 fread an IC-7300's frequency
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 F 14074000 # set it (20 m FT8)
rigctld -m 3073 -r /dev/ttyUSB0 &share the radio with other programs

Options

-m ID
the radio model (from -l)
-r DEVICE
its serial port
-s BAUD
the serial speed
-l
list every supported model
-P TYPE
how PTT is keyed (RIG, DTR, RTS...)

Notes

  • The serial port belongs to dialout; Copal adds you with the radio and Geiger counter setup, as id will show.
  • Model 1 is Hamlib's dummy radio: every command works on it with no hardware, which makes it the place to learn the commands.

See also direwolf

rtl_power_fftw Scan a wide band of spectrum with an RTL-SDR and record the power at each frequency.

Radio · command-line tool · rtl-power-fftw 20200601 · stage 12 · The application catalogue · man rtl_power_fftw(1) · home

needs fftw-single-libs, librtlsdr

On Copal: The catalogue's spectrum survey: sweep hundreds of megahertz in steps and see where the signals are -- faster and finer than rtl_power, thanks to FFTW.

rtl_power_fftw [OPTION ...]

Use

Give a frequency or a range; it steps the tuner across it and prints the power in each bin, as text a plotting program reads directly.

Examples

rtl_power_fftw -f 88M:108M -b 512 -n 100 > fm.datthe FM band, once
rtl_power_fftw -f 430M:440M -b 1024 -c -e 3600 -q > 70cm.datan hour, continuously
rtl_power_fftw -f 1090M -b 256 -t 10one frequency, 10 seconds

Options

-f HZ | HZ:HZ
one frequency or a range to sweep
-b N
bins in each FFT (resolution)
-n N
spectra to average per step
-t SECS
integration time per step
-c
continue: sweep until stopped
-e SECS
stop after SECS seconds
-g GAIN
tuner gain, in tenths of a dB
-q
quiet: data only

Notes

  • It comes from Alpine's testing repository (rtl-power-fftw@testing).
  • The same dongle rules apply as for rtl_test: the plugdev group and the TV driver kept off it.

See also rtl_test, gnuplot, fftw-wisdom

rtl_test Test an RTL-SDR dongle -- and, with its siblings, tune, record and scan with one.

Radio · command-line tool · rtl-sdr 2.0.2 · stage 12 · The application catalogue · home

needs librtlsdr

On Copal: The catalogue's rtl-sdr tools, for the cheap RTL2832U USB dongle that turns a Pi into a wide-band radio receiver. rtl_test is the first command: is the stick there, and does it keep up?

Use

Plug the dongle in and run rtl_test: it names the tuner, then counts lost samples; none lost means the USB link keeps up. The same package has rtl_fm (listen), rtl_sdr (record raw samples), rtl_power (scan) and rtl_tcp (serve it to another machine).

Examples

rtl_testfind the dongle, check for lost samples
rtl_test -pmeasure its frequency error, in ppm
rtl_fm -f 96.3M -M wbfm -s 200k -r 48k - | aplay -r 48000 -f S16_LEFM radio
rtl_sdr -f 433.92M -s 1.024M -n 10240000 capture.binten seconds of raw samples
rtl_tcp -a 0.0.0.0serve it to Gqrx or SDR# on another machine

Options

-d INDEX
which dongle, when there are several
-s RATE
the sample rate (default 2048000)
-p[SECS]
measure the PPM error over SECS seconds
-t
the E4000 tuner benchmark

Notes

  • "usb_claim_interface error -6": the kernel's TV driver took the stick. Copal blacklists it from 24 Sep 2026 (/etc/modprobe.d/copal-rtl-sdr.conf); unplug and plug in again.
  • "usb_open error -3": no permission. The device belongs to the group plugdev, which Copal adds you to from the same date; log in again after.
  • A ppm figure from -p goes to other tools as -p N (rtl_fm) or the frequency correction setting (Gqrx).

See also rtl_power_fftw, dump1090, direwolf, gqrx

Retro

mednafen One emulator for many consoles: NES, SNES, Game Boy, Mega Drive, PC Engine, PlayStation, Saturn.

Retro · command-line tool · mednafen 1.32.1 · stage 12 · The application catalogue · home

needs libflac, sdl2, alsa-lib, zlib

On Copal: The catalogue's multi-system emulator: one command for most of the classic consoles, accurate enough for the demanding ones, driven entirely from the keyboard.

Usage: /usr/bin/mednafen [OPTION]... [FILE]
Options:

Use

Give it a game file (a ROM, or a CD image's .cue) and it picks the system from the file. It opens a window; F1 shows the keys. Settings are command-line switches named after the settings in its config file.

Examples

mednafen game.nesplay
mednafen game.cuea CD game, from its cue sheet
mednafen -video.fs 1 game.sfcfull screen
mednafen -force_module md game.binsay which system when the file does not
F1 (in the game) the list of keys
Alt-Shift-1 configure controller 1's buttons
F5 F7 save state / load state
Alt-Enter full screen

Options

-force_module NAME
the system: nes, snes, gb, gba, md, pce, psx, ss...
-which_medium N
which disc, for a multi-disc game
-soundrecord FILE
record the sound to a WAV
-help
the options it takes on the command line

Notes

  • PlayStation, Saturn and PC Engine CD need the console's BIOS files, which cannot be distributed: they go in ~/.mednafen/firmware/, and mednafen names the file it wants when one is missing.
  • Every setting in ~/.mednafen/mednafen.cfg is also a switch: -psx.bios_na FILE, -video.driver opengl.
  • Games are yours to bring: only dump cartridges and discs you own.

See also copal-store

Science

gnuplot Plot functions and data files, in a window, to an image, or as text in the terminal.

Science · command-line tool · gnuplot 6.0.4 · stage 12 · The application catalogue · man gnuplot(1) · home

needs libx11, cairo, libcerf, libgd, glib, pango, readline, libwebp

On Copal: The catalogue's plotter, and the one Octave, Maxima and ngspice draw through. A plot of a data file is one line.

gnuplot [X11 options] [options] [file ...]

Use

plot a function or a file's columns. Where the plot goes is the terminal setting: a window, a PNG or SVG file, or the text terminal itself (dumb, or sixelgd in a terminal that shows sixel images).

Examples

gnuplot -p -e 'plot sin(x)'a window that stays open
gnuplot -e 'set terminal dumb; plot sin(x)'as text, over SSH
gnuplot -e "set terminal pngcairo; set output 'p.png'; plot 'data.txt' using 1:2 with lines"
gnuplot script.gpa file of commands
gnuplotthe prompt
plot 'data.csv' using 1:3 with lines (at the prompt) columns 1 and 3
set datafile separator ',' for CSV
replot draw again after a change

Options

-e 'CMDS'
run the commands (separated by ;)
-p
persist: keep the window after gnuplot exits -c FILE ARGS run FILE with arguments
-d
ignore any ~/.gnuplot initialisation file

Notes

  • The terminals this build has: x11 (a window), pngcairo, svg, sixelgd, kittycairo, and dumb. set terminal lists them all.
  • A CSV needs set datafile separator ','; otherwise columns are split on whitespace.

See also octave, maxima, ngspice, python3

gp PARI/GP: a calculator for number theory -- huge integers, primes, factoring, elliptic curves.

Science · terminal program · pari 2.17.3 · stage 12 · The application catalogue · man gp(1) · home

needs pari-libs, readline

On Copal: The catalogue's number-theory system: exact arithmetic on numbers with thousands of digits, fast, at an interactive prompt.

gp [-s stacksize] [-p primelimit] [--emacs] [-f|--fast] [-q|--quiet] [-D|--default key=val]
[--help] [--test] [--texmacs] [--version] [--version-short] [ file1 file2 ...]

Use

Type an expression at the ? prompt and get the answer. Integers are exact at any size; \p sets the decimal precision for everything else.

Examples

gpthe prompt
echo 'factor(2^128+1)' | gp -qone computation, quietly
gp -q script.gprun a file
factor(2^67 - 1) (at the prompt) factor a number
isprime(10^100 + 267) is it prime?
nextprime(10^50) the next prime
\p 100 100 digits of precision; Pi then shows them
?factor help on one function; \q quit

Options

-q, --quiet
no banner
-s SIZE
the initial stack size
-p N
precompute primes up to N
--default KEY=VAL
set a default at start: --default realprecision=50

Notes

  • "the PARI stack overflows": it grows the stack itself up to parisizemax; for very large computations, default(parisizemax, "2G").
  • ? alone lists the help sections; ??factor is the long manual entry.

See also maxima, Singular

maxima Computer algebra: solve, simplify, differentiate, integrate -- exactly, with symbols.

Science · terminal program · maxima 5.48.1 · stage 12 · The application catalogue · man maxima(1) · home

needs texinfo, shared-mime-info, ecl

On Copal: The catalogue's symbolic mathematics: the answer as a formula, not a number -- integrals, limits, series, systems of equations.

maxima [options]

rmaxima [options]

xmaxima [options]

Use

Type expressions at the (%i1) prompt, each ending with ; (show the result) or $ (hide it). % is the last result. Everything stays exact until you ask for a number with float().

Examples

maximathe prompt
maxima --batch-string='integrate(x*sin(x), x);'one computation, then exit
maxima -b work.macrun a file of commands
diff(x^3*sin(x), x); (at the prompt) differentiate
integrate(1/(1+x^2), x, 0, 1); a definite integral: %pi/4
solve([x+y=3, x-y=1], [x,y]); a system of equations
float(%pi); a number
quit(); leave

Options

-b, --batch FILE
run FILE and exit
--batch-string=STR
run STR and exit
-q, --quiet
no banner
-r, --run-string=STR
run STR, then stay at the prompt

Notes

  • Every input ends with ; or $. Without one, Maxima waits for more.
  • plot2d(sin(x), [x, 0, 6]) draws with gnuplot.
  • It comes from Alpine's testing repository (maxima@testing).

See also octave, gp, Singular, gnuplot

octave GNU Octave: numerical computing in a language compatible with MATLAB.

Science · terminal program · octave 11.1.0 · stage 12 · The application catalogue · man octave(1) · home

needs qt6-qtbase-sqlite, openblas, mesa-gl, glu, graphicsmagick-c++, graphicsmagick, qt6-qtbase, qt6-qt5compat

On Copal: The catalogue's MATLAB-alike: matrices, linear algebra, signal processing and plots, and most MATLAB scripts run unchanged.

octave [options]... [file]

Use

Type at the >> prompt, or run a .m script. Everything is a matrix; ; at the end of a line stops it printing the result.

Examples

octavethe prompt
octave script.mrun a script
octave --eval 'disp(inv([2 1; 1 3]))'one expression
octave --no-guithe terminal prompt, never a window
A = [1 2; 3 4]; (at the prompt) a matrix
x = A \ [5; 6] solve A x = b
plot(sin(0:0.1:6)) a plot, in a window
pkg list the installed packages; exit leave

Options

--eval CODE
run CODE and exit
--no-gui
the command line, no window
-q, --quiet
no banner
-W, --no-window-system
no graphics at all (plots fail; for scripts)
--path DIR
add DIR to the function search path

Notes

  • Plots open a window, so they need the desktop. Over SSH, use graphics_toolkit gnuplot and set terminal dumb for ASCII, or print -dpng plot.png to save the figure.
  • Octave-Forge packages (pkg install -forge NAME) build from source and need build-base; several are in Alpine as octave-NAME.

See also python3, R, gnuplot, maxima

pdflatex Typeset a LaTeX document straight to PDF.

Science · command-line tool · texlive 2026.0 · stage 12 · The application catalogue · man pdflatex(1) · home

needs ghostscript, perl, texmf-dist, texmf-dist-latex, libx11, cairo, gmp, icu-libs

On Copal: TeX Live, for papers, theses, letters and anything with equations. Stage 14 asks which: texlive, a few hundred MB, or texlive-full, about 4 GB, with every package there is.

pdftex [options] [&format] [file|\commands]

Use

Write the document as a .tex file; pdflatex turns it into a .pdf. Cross-references, a table of contents and citations need a second run, because the first only records where things are.

Examples

pdflatex paper.texpaper.pdf
pdflatex paper.tex && pdflatex paper.textwice: references settle
pdflatex -interaction=nonstopmode paper.texdo not stop at errors
latexmk -pdf paper.texas many runs as needed, bibliography too
kpsewhich tikz.styis this package installed?

Options

-interaction=nonstopmode
carry on through errors, no prompt
-halt-on-error
stop at the first error
-output-directory=DIR
write the PDF and logs there
-jobname=NAME
name the output NAME.pdf
-shell-escape
let the document run commands (minted needs it)

Notes

  • "File tikz.sty' not found" means the package is not installed. With the smaller texlive, add a collection: doas apk add texmf-dist-pictures (TikZ), texmf-dist-latexextra` (most others).
  • At an error it waits at a ? prompt: x Enter leaves. The real message is a few lines above, and in the .log.
  • Keep -shell-escape for documents you wrote: it lets the document run programs.

See also gnuplot, octave, maxima

python3 The Python interpreter: scripts, a calculator, and a large standard library.

Science · command-line tool · python3 3.14.7 · stage 4 · X.Org, i3, a terminal and a browser · man python3(1) · home

needs libssl3, libexpat, libbz2, libcrypto3, libffi, gdbm, xz-libs, mpdecimal

On Copal: Several of Copal's own tools are Python, and so is a good share of what people run on a Pi. Stage 4 installs it; the catalogue's Science section adds the numerical packages.

python [ -B ] [ -b ] [ -d ] [ -E ] [ -h ] [ -i ] [ -I ]
       [ -m module-name ] [ -q ] [ -R ] [ -O ] [ -OO ] [ -P ] [ -s ] [ -S ] [ -u ]
       [ -v ] [ -V ] [ -W argument ] [ -x ] [ -X option ] [ -?  ]
       [ --check-hash-based-pycs default | always | never ]
       [ --help ] [ --help-env ] [ --help-xoptions ] [ --help-all ]
       [ -c command | script | - ] [ arguments ]

Use

Run a script, or start the interactive prompt and type. Third-party packages come from apk first (py3-NAME), and from pip inside a virtual environment when apk has not got them.

Examples

python3the interactive prompt; Ctrl-D leaves
python3 script.pyrun a script
python3 -c 'print(2**64)'one line
python3 -m http.server 8000serve this directory on port 8000
python3 -m venv .venva private environment for a project...
. .venv/bin/activate...enter it (deactivate to leave)
python3 -m json.tool data.jsonpretty-print JSON
python3 -m pdb script.pystep through it in the debugger

Options

-c CMD
run CMD
-m MODULE
run a module as a script: venv, http.server, pdb, json.tool, pip
-i
stay at the prompt after the script ends
-u
unbuffered output (for logs and pipes)
-V
the version

Notes

  • pip install outside a virtual environment says "externally-managed-environment". That is deliberate: the system's Python belongs to apk. apk add py3-NAME if it exists, or a venv.
  • Packages with C parts often have no ready wheel for musl and build from source: apk add build-base python3-dev first.
  • Python 2 is gone: python is Python 3 too, but scripts written for Copal say python3, which works on every system that has it.

See also pip, gdb, nvim

R The R language for statistics and graphics.

Science · terminal program · R 4.6.0 · stage 12 · The application catalogue · man R(1) · home

needs R-mathlib, tzdata, openblas, libx11, libxmu, libxt, libbz2, cairo

On Copal: The catalogue's statistics environment: data frames, models, tests and plots, with CRAN's twenty thousand packages behind it.

R [options] [< infile] [> outfile]
R CMD command [arguments]

Use

Type at the > prompt, or run a script with Rscript. Data frames hold tables; summary(), lm() and plot() do most of the everyday work.

Examples

Rthe prompt
Rscript analysis.Rrun a script
R -q -e 'summary(mtcars)'one expression
R --vanillano saved workspace, no profiles
d <- read.csv("data.csv") (at the prompt) load a table
summary(d) the statistics of each column
fit <- lm(y ~ x, data=d) a linear model; summary(fit)
install.packages("ggplot2") a package from CRAN
q() leave

Options

-q, --quiet
no banner
-e EXPR
evaluate EXPR (with R -q -e)
--vanilla
no profile, no saved workspace
--no-save
do not save the workspace on exit
-f FILE
read commands from FILE

Notes

  • The system library is not writable: the first install.packages() offers a personal library in your home -- answer yes.
  • Packages with C or Fortran compile from source on Alpine (no binary packages for musl) and need build-base and gfortran; the first install of a big one takes a while.
  • q() asks whether to save the workspace; n, or it reloads into every later session.

See also python3, octave, gnuplot

Singular Computer algebra for polynomials: Gröbner bases, ideals, singularities.

Science · terminal program · singular 4.4.1_p5 · stage 12 · The application catalogue · man Singular(1) · home

needs python3, cddlib, flint, gmp

On Copal: The catalogue's polynomial-algebra system, the tool of commutative algebra and algebraic geometry. The command has a capital S.

Singular [options] [file1 [file2 ...]]

ESingular [options] [file1 [file2 ...]]

TSingular [options] [file1 [file2 ...]]

Use

Declare a ring -- the field, the variables, the ordering -- then work in it with polynomials and ideals. Every statement ends with ;.

Examples

Singularthe prompt (capital S)
Singular -q script.singrun a file
ring r = 0, (x,y,z), dp; (at the prompt) rational coefficients, x y z
ideal I = x2 - y, y2 - z; an ideal (x2 is x^2)
std(I); its Gröbner basis
help std; help on a command
quit; leave

Options

-q, --quiet
no banner, and quit at the end of a file
-b, --batch
batch mode
--no-rc
do not read the .singularrc file
-c CMD
run CMD first

Notes

  • The command is Singular; singular is not found.
  • In a ring declared with short variable names, x2y means x^2*y.

See also maxima, gp

Security

aircrack-ng a 802.11 WEP / WPA-PSK key cracker

Security · command-line tool · aircrack-ng 1.7 · stage 12 · The application catalogue · man aircrack-ng(1) · home

needs ethtool, wireless-tools, iw, sqlite, grep, libcrypto3, libnl3, libpcap

aircrack-ng [options] <input file(s)>

No notes yet: the facts above are read from apk and the man page.

clamscan scan files and directories for viruses

Security · command-line tool · clamav-scanner 1.4.6 · stage 12 · The application catalogue · man clamscan(1) · home

needs freshclam, clamav-libs, zlib

clamscan [options] [file/directory/-]

No notes yet: the facts above are read from apk and the man page.

fail2ban-client configure and control the server

Security · command-line tool · fail2ban 1.1.0 · stage 12 · The application catalogue · man fail2ban-client(1) · home

needs python3, iptables, logrotate

fail2ban-client [OPTIONS] <COMMAND>

No notes yet: the facts above are read from apk and the man page.

john John the Ripper password cracker

Security · command-line tool · john 1.9.0 · stage 12 · The application catalogue · home

needs nss, opencl, libcrypto3, gmp, libgomp, libpcap, zlib

Usage: john [OPTIONS] [PASSWORD-FILES]
--single[=SECTION[,..]]    "single crack" mode, using default or named rules
--single=:rule[,..]        same, using "immediate" rule(s)
--wordlist[=FILE] --stdin  wordlist mode, read words from FILE or stdin

No notes yet: the facts above are read from apk and the man page.

lynis System and security auditing tool

Security · command-line tool · lynis 3.1.6 · stage 12 · The application catalogue · man lynis(8) · home

needs bash

lynis [scan mode] [other options]

No notes yet: the facts above are read from apk and the man page.

nmap Network exploration tool and security / port scanner

Security · command-line tool · nmap 7.99 · stage 12 · The application catalogue · man nmap(1) · home

needs libcrypto3, lua5.4-libs, libpcap, libssh2, libssl3, zlib

nmap [Scan Type...] [Options] {target specification}

No notes yet: the facts above are read from apk and the man page.

suricata Suricata

Security · command-line tool · suricata 8.0.7 · stage 12 · The application catalogue · man suricata(1) · home

needs python3, py3-yaml, libbpf, libcap-ng, hiredis, vectorscan, jansson, lz4-libs

suricata [OPTIONS] [BPF FILTER]

No notes yet: the facts above are read from apk and the man page.

tcpdump dump traffic on a network

Security · command-line tool · tcpdump 4.99.6 · stage 10 · Wireless, audio, capture and disks · man tcpdump(1) · home

needs libcrypto3, libpcap

tcpdump [ -AbdDefghHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ]
        [ -c count ] [ --count ] [ -C file_size ]
        [ -E spi@ipaddr algo:secret,...  ]
        [ -F file ] [ -G rotate_seconds ] [ -i interface ]
        [ --immediate-mode ] [ -j tstamp_type ] [ -m module ]
        [ -M secret ] [ --number ] [ --print ] [ -Q in|out|inout ]
        [ -r file ] [ -s snaplen ] [ -T type ] [ --version ] [ -V file ] [ -w file ] [ -W
filecount ]
        [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
        [ --time-stamp-precision=tstamp_precision ] [ --micro ] [ --nano ]
        [ expression ]

No notes yet: the facts above are read from apk and the man page.

termshark terminal UI for tshark, inspired by Wireshark

Security · terminal program · termshark 2.4.0 · stage 10 · Wireless, audio, capture and disks · home

needs tshark

No notes yet: the facts above are read from apk and the man page.

tshark Dump and analyze network traffic

Security · command-line tool · tshark 4.6.6 · stage 10 · Wireless, audio, capture and disks · man tshark(1) · home

needs glib, libnl3, libpcap, wireshark-common

tshark [ -i <capture interface>|- ] [ -f <capture filter> ] [ -2 ] [ -r <infile> ]
[ -w <outfile>|- ] [ options ] [ <filter> ]

tshark -h|--help

tshark -v|--version

No notes yet: the facts above are read from apk and the man page.

ufw program for managing a netfilter firewall

Security · command-line tool · ufw 0.36.2 · stage 12 · The application catalogue · man ufw(8) · home

needs iptables, python3

No notes yet: the facts above are read from apk and the man page.

Services

openrc Alpine's init system: starts and stops services by runlevel.

Services · openrc 0.63.2 · Alpine's base system · man openrc(8) · home

needs ifupdown-any, openrc-user, libcap2

On Copal: Every service on a Copal machine -- sshd, chronyd, bluetooth, seatd, acpid -- is an OpenRC script in /etc/init.d, and every stage that enables one does it with rc-update. There is no systemd here.

openrc [-n, --no-stop] [-o, --override] [runlevel]

Use

Switch the machine to a runlevel: OpenRC starts what that runlevel lists and stops what it does not. At boot it runs sysinit, then boot, then default; you rarely call openrc by hand. The day-to-day commands are rc-service (start and stop one), rc-update (what starts at boot) and rc-status (what is running).

Examples

rc-statusthe current runlevel and its services
doas openrc defaultbring the default runlevel back up
doas openrc nonetworkdrop to the runlevel without networking
ls /etc/init.devery service this machine could run
ls /etc/local.dCopal's boot-time scripts (*.start)

Options

RUNLEVEL
switch to it: sysinit, boot, default, nonetwork, shutdown
-n, --no-stop
start the runlevel's services, stop none of the others
-S, --sys
the kind of system OpenRC thinks it is on (VM, container...)
-v, --verbose
say what it does

Notes

  • The systemd answers online do not apply: no systemctl, no journalctl, no unit files. systemctl restart sshd is rc-service sshd restart; systemctl enable sshd is rc-update add sshd; the journal is /var/log/messages.
  • A runlevel is a directory, /etc/runlevels/NAME, of links to /etc/init.d scripts. rc-update edits those links; editing them by hand works too.
  • /etc/local.d/*.start run at the end of boot, through the local service -- Copal's zram swap is started from there (stage 5). A script is run only if it is executable.
  • /etc/rc.conf holds the global settings. Two worth knowing, both off: rc_parallel, and rc_logger, which when on writes the whole boot to /var/log/rc.log -- the thing to turn on when a boot goes wrong too fast to read.

See also rc-service, rc-update, rc-status

rc-service Start, stop, restart or ask about one OpenRC service.

Services · openrc 0.63.2 · Alpine's base system · man rc-service(8) · home

needs ifupdown-any, openrc-user, libcap2

On Copal: The command every stage uses to bring a service up once it is installed, and the one to reach for when a service needs a kick: sshd after an edit to its config, bluetooth after a pairing sulks.

rc-service [-c, --ifcrashed] service cmd [...]
rc-service -d, --debug service cmd [...]
rc-service -D, --nodeps service cmd [...]
rc-service [-i, --ifexists] service cmd [...]
rc-service [-I, --ifinactive] service cmd [...]
rc-service [-N, --ifnotstarted] service cmd [...]
rc-service [-s, --ifstarted] service cmd [...]
rc-service [-S, --ifstopped] service cmd [...]
rc-service -e, --exists service
rc-service -Z, --dry-run service cmd [...]
rc-service -l, --list
rc-service -r, --resolve service

Use

Run a service's script with a verb: start, stop, restart, status, and whatever else that script offers. It finds the script (in /etc/init.d or /usr/local/etc/init.d) and resolves the services it needs first. service is the same command under its old name.

Examples

rc-service sshd statusrunning or not
doas rc-service sshd restartafter editing /etc/ssh/sshd_config
doas rc-service bluetooth startstart one now (not at boot)
rc-service -levery service there is
doas rc-service -s chronyd restartrestart only if it is running
doas rc-service syncthing zapforget a state that is wrong

Options

start, stop, restart
the usual verbs; status says started, stopped or crashed
zap
reset the recorded state to stopped, running nothing
-l, --list
list every service
-e, --exists NAME
exit 0 if the service exists
-i, --ifexists
run the verb only if the service exists
-s, --ifstarted
run the verb only if it is started
-S, --ifstopped
run the verb only if it is stopped
-D, --nodeps
ignore its dependencies
-d, --debug
trace the script as it runs (set -x)

Notes

  • Starting a service does not make it start at boot. That is rc-update add NAME; the two are separate on purpose.
  • "already starting" or a service shown as started that plainly is not: its recorded state is out of step with reality. rc-service NAME zap resets it, then start again.
  • status needs no root; anything that changes a service does.
  • Stopping a service also stops the services that need it -- stopping dbus takes bluetooth down with it. OpenRC says so as it does it.

See also rc-update, rc-status, openrc

rc-status Show which services are running, runlevel by runlevel.

Services · openrc 0.63.2 · Alpine's base system · man rc-status(8) · home

needs ifupdown-any, openrc-user, libcap2

On Copal: The first question after a boot that went wrong, or a desktop piece that is missing: is its service started, stopped or crashed. No root needed.

rc-status [-C] [-f ini] [-i state] [runlevel]
rc-status [-C] [-f ini] [-a | -m | -S | -s | -u]
rc-status [-C] [-c | -l | -r]

Use

List the current runlevel's services and their state. With -a it shows every runlevel; with -c only what has crashed, which after a bad boot is usually the short list you want.

Examples

rc-statusthe current runlevel
rc-status -aevery runlevel
rc-status -conly crashed services
rc-status -mstarted by hand, in no runlevel
rc-status -uinstalled but in no runlevel
rc-status -rthe name of the current runlevel

Options

-a, --all
services in every runlevel
-c, --crashed
only crashed services
-m, --manual
services started by hand, not by a runlevel
-u, --unused
services in no runlevel
-s, --servicelist
every service and its state, as one list
-r, --runlevel
print the current runlevel's name
-f ini
output a script can parse

Notes

  • "crashed" means OpenRC started it and its process has gone. The cause is in /var/log/messages or the service's own log, not here; restart it with rc-service NAME restart.
  • A service missing from the list is in no runlevel -- rc-status -u to find it, rc-update add to put it in one.

See also rc-service, rc-update, openrc

rc-update Choose which services start at boot, and in which runlevel.

Services · openrc 0.63.2 · Alpine's base system · man rc-update(8) · home

needs ifupdown-any, openrc-user, libcap2

On Copal: How every stage enables what it installs -- sshd and chronyd in stage 1, acpid, bluetooth, seatd and the rest later. Undoing one of those choices is rc-update del.

rc-update [-s, --stack] add service [runlevel ...]
rc-update [-s, --stack] [-a, --all] delete service [runlevel ...]
rc-update [-u, --update] [-v, --verbose] show [runlevel ...]

Use

Add a service to a runlevel, or take it out. Most services belong in default; a few that must run before the network or the desktop go in boot. rc-update with no arguments shows what starts where.

Examples

rc-updateevery enabled service and its runlevel
doas rc-update add syncthing default # start it at every boot from now on
doas rc-update del bluetooth default # stop starting it at boot
doas rc-update del -a oldthingout of every runlevel, e.g. after removing it
rc-update show -vevery service, enabled or not

Options

add NAME [LEVEL]
enable in LEVEL; with no level, the current one (default)
del NAME [LEVEL]
disable in LEVEL; delete is the same word
show [LEVEL]
what is enabled, and where
-a, --all
with del: from every runlevel
-v, --verbose
with show: list the services in no runlevel too
-u, --update
rebuild the dependency cache (after clock skew)

Notes

  • Enabling does not start it now: rc-update add X and then rc-service X start, or wait for the next boot.
  • Removing a package can leave its service in a runlevel; OpenRC then complains at boot about a script that is not there. rc-update del -a NAME clears it.
  • "clock skew detected": a file in /etc is newer than the clock, which happens on a Pi with no real-time clock before chronyd has set the time. It passes once the time is right; rc-update -u forces the rebuild.

See also rc-service, rc-status, openrc

Sharing

croc Send a file or a folder to another computer, with a code phrase, from one command.

Sharing · command-line tool · croc 10.2.2 · stage 12 · The application catalogue · home

On Copal: The catalogue's quickest way to hand a file to someone: no shared network, accounts or server set-up. Encrypted end to end.

USAGE:
   croc [GLOBAL OPTIONS] [COMMAND] [COMMAND OPTIONS] [filename(s) or folder]
   USAGE EXAMPLES:

Use

The sender runs croc send FILE and gets a code phrase. The receiver runs croc with that phrase, on any machine with croc, and the file arrives. Both sides meet through a relay, which never sees the contents.

Examples

croc send photo.jpgprints a code phrase to pass on
croc send ~/Documents/reporta whole folder
croc send --text 'meet at 3'a line of text
CROC_SECRET=7-lemon-orbit-jazz crocreceive, with the phrase you were given

Options

send FILE...
send files or folders
send --text T
send a line of text instead of a file
send --code P
choose the phrase yourself
--yes
accept without asking (receiving)
--relay ADDR
use another relay, such as your own
--classic
accept the phrase as an argument (less safe)

Notes

  • On Linux the phrase goes in CROC_SECRET, not on the command line, where other users could see it in the process list: croc refuses it as an argument and says so. --classic restores the old way.
  • The default relay is a public one run by croc's author; croc relay runs your own.

See also rsync, syncthing, darkhttpd

darkhttpd Serve a folder over HTTP, with one command and no configuration.

Sharing · command-line tool · darkhttpd 1.17 · stage 12 · The application catalogue · home

On Copal: The catalogue's smallest web server: share a folder of files on the LAN for a minute, or preview a static site from its output folder.

usage:	/usr/bin/darkhttpd /path/to/wwwroot [flags]
flags:	--port number (default: 8080, or 80 if running as root)
		Specifies which port to listen on for connections.

Use

Give it a folder; it serves it on port 8080 until Ctrl-C, with a listing of the files where there is no index.html.

Examples

darkhttpd ~/Publichttp://this-machine:8080/
darkhttpd public --port 8000a built site, on port 8000
darkhttpd . --addr 127.0.0.1this machine only
darkhttpd ~/Public --no-listingno folder listings

Options

--port N
the port (default 8080)
--addr IP
listen on one address only (default: all)
--no-listing
do not list folders without an index.html
--index FILE
the index file (default index.html)
--log FILE
write an access log

Notes

  • By default it listens on every address, so anyone on the network can read the folder. --addr 127.0.0.1 keeps it to this machine.
  • It serves files as they are: no PHP, no uploads, no passwords.
  • A service is installed too (/etc/init.d/darkhttpd) for serving a folder permanently; /etc/conf.d/darkhttpd says which.

See also hugo, zola, croc, python3

rsync Copy and synchronise files, locally or over SSH, sending only differences.

Sharing · command-line tool · rsync 3.5.0 · stage 12 · The application catalogue · man rsync(1) · home

needs acl-libs, lz4-libs, popt, libxxhash, zlib, zstd-libs

On Copal: Stage 11's snapshots are rsync, and so is moving a home directory to a new card or a backup to another machine; the catalogue carries it for copying trees between machines.

Local:
    rsync [OPTION...] SRC... [DEST]

Access via remote shell:
    Pull:
        rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    Push:
        rsync [OPTION...] SRC... [USER@]HOST:DEST

Access via rsync daemon:
    Pull:
        rsync [OPTION...] [USER@]HOST::SRC... [DEST]
        rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    Push:
...

Use

Keep one tree identical to another. Only changed files cross, and only the changed parts of them, so the second run over a large tree takes seconds.

Examples

rsync -av ~/Photos/ /media/usb/Photos/copy a tree, keeping times and modes
rsync -avz --delete ~/code/ pi:code/mirror to another machine over SSH
rsync -avn --delete src/ dst/dry run: what would change
rsync -aP big.iso pi:/tmp/resumable, with a progress bar
rsync -aHAX / /media/snapshots/today/a whole system: links, ACLs, attributes

Options

-a
archive: recursive, keeps symlinks, modes, times, owner, group
-v
name each file
-z
compress in transit (for a slow link, not a LAN)
-n
dry run
-P
--partial --progress: keep partial files, show progress
--delete
remove files in the destination that the source lacks
-e 'ssh -p 2222'
the remote shell, with its options --exclude=PATTERN skip matching paths
-H -A -X
keep hard links, ACLs and extended attributes

Notes

  • The trailing slash is the whole question. src/ copies the contents of src; src copies the directory itself, into the destination.
  • --delete with the wrong direction or a missing slash deletes the wrong files. Run it with -n first.
  • -a does not keep hard links, ACLs or extended attributes; add -HAX for a system copy, as the snapshot stage does.

See also ssh, lftp

smbd Samba's file server: share folders with Windows and macOS machines over SMB.

Sharing · command-line tool · samba-server 4.23.8 · stage 12 · The application catalogue · man smbd(8) · home

needs samba-client-libs, samba-common, samba-common-server-libs, samba-libs, samba-util-libs, libauth-samba, libwbclient, acl

On Copal: The catalogue's way to make the Pi's files appear in Finder or Explorer like any network drive. Alpine's default configuration already shares each user's home folder, once the user has a Samba password.

smbd [-D|--daemon] [-i|--interactive] [-F|--foreground] [--no-process-group]
 [-b|--build-options] [-p <port number(s)>] [-P <profiling level>] [-d <debug level>]
 [--debug-stdout] [--configfile=<configuration file>] [--option=<name>=<value>]
 [-l|--log-basename <log directory>] [--leak-report] [--leak-report-full] [-V|--version]

Use

Give your account a Samba password, start the service, and connect from the other machine: smb://PI/yourname in macOS Finder (Cmd-K), or \\PI\yourname in Windows Explorer. More shares are sections in /etc/samba/smb.conf.

Examples

doas smbpasswd -a $USERa Samba password for your account (once)
doas rc-service samba startstart it now
doas rc-update add sambaand at every boot
testparm -scheck smb.conf, and print what is in force
smbd -b | headhow this Samba was built

Options

-F, --foreground
run in the foreground (for debugging)
-i, --interactive
run interactively, logging to the terminal
-s, --configfile=F
another configuration file
-b, --build-options
print the build options
-V, --version
the version

Notes

  • The Samba password is separate from your login password: smbpasswd sets it, and a share refuses you until it is set.
  • The service is samba, which starts smbd and nmbd together; the command itself is rarely run by hand.
  • A share for a folder of its own: [music] then path = /home/you/Music and read only = no in smb.conf, then doas rc-service samba restart.

See also sshfs, syncthing, rc-service

sshfs Mount a folder from another machine over SSH, and use it like a local one.

Sharing · command-line tool · sshfs 3.7.6 · stage 12 · The application catalogue · man sshfs(1) · home

needs openssh-client, fuse3, fuse3-libs, glib

On Copal: The catalogue's network folder with nothing to set up on the other side: anywhere you can ssh to, you can mount. No root needed on Copal.

To mount a filesystem:

   sshfs [user@]host:[dir] mountpoint [options]

If host is a numeric IPv6 address, it needs to be enclosed in square brackets.

To unmount it:

   fusermount3 -u mountpoint   # Linux
   umount mountpoint           # OS X, FreeBSD

Use

Mount a remote folder onto an empty local one; programs then read and write it as if it were here. Unmount with fusermount3 -u when done.

Examples

mkdir -p ~/mnt/pi
sshfs pi:/home/you/Music ~/mnt/pimount
sshfs -o reconnect pi:Music ~/mnt/pisurvive a dropped connection
sshfs -p 2222 you@example.org:/srv ~/mnt/srvsshd on another port
fusermount3 -u ~/mnt/piunmount

Options

-p PORT
the SSH port
-o reconnect
reconnect after the connection drops
-o idmap=user
show the remote files as yours
-o follow_symlinks
follow links on the remote side
-f
stay in the foreground (to see errors)

Notes

  • Unmounting is fusermount3 -u, not umount: a plain user may not umount.
  • Everything goes through ssh, so ~/.ssh/config hosts and keys work: sshfs pi: is enough when pi is a host there.
  • A folder full of large files is slow to list over a slow link; for copying many files, rsync is faster.

See also ssh, smbd, rsync

syncthing Keep folders in sync between your machines, directly, with no server in between.

Sharing · command-line tool · syncthing 2.1.0 · stage 12 · The application catalogue · man syncthing(1) · home

needs sqlite-libs

On Copal: The catalogue's continuous sync: a folder on the Pi and the same folder on the Mac or a phone stay identical, over the LAN or the internet, encrypted.

syncthing [serve]
          [--home=<dir> | --config=<dir> --data=<dir>]
          [--allow-newer-config] [--audit] [--auditfile=<file|-|-->]
          [--db-maintenance-interval=<interval>]
          [--db-delete-retention-interval=<interval>]
          [--gui-address=<address>] [--gui-apikey=<key>]
          [--log-level=<level>] [--log-file=<filename>]
          [--log-max-old-files=<num>] [--log-max-size=<num>]
          [--log-format-timestamp=<format>] [--no-log-format-level-string]
          [--log-format-level-syslog]
          [--no-browser] [--no-console]
          [--no-port-probing] [--no-restart] [--no-upgrade]
          [--paused] [--unpaused]
          [--version] [--help] [--debug-*]
...

Use

Run it as yourself; it serves a web page at 127.0.0.1:8384 where you add the other machines (by their device ID) and choose which folders to share. After that it works in the background.

Examples

syncthingstart it (and open the web page)
syncthing serve --no-browserstart without opening a browser
syncthing device-idthis machine's ID, to give the others
syncthing pathswhere its config and database are
syncthing browseropen its web page in the browser

Options

serve
run it (the default command) --no-browser with serve: do not open the web page --gui-address=URL with serve: the page elsewhere, e.g. 0.0.0.0:8384
device-id
print this device's ID
paths
where its files are
-H, --home=PATH
another config and database directory

Notes

  • Run it as yourself, not the system service: the service runs as the user syncthing, which cannot read or write your home folder. exec-once = syncthing serve --no-browser in ~/.config/hypr/local.conf starts it with the desktop.
  • To see the web page from another machine, an SSH tunnel keeps it private: ssh -L 8384:127.0.0.1:8384 pi, then browse to localhost:8384 there.
  • A deleted file is deleted everywhere. Turn on file versioning for a folder if that worries you.

See also rsync, unison, croc

unison Two-way file synchronisation: changes on either side are carried to the other.

Sharing · command-line tool · unison 2.54.0 · stage 12 · The application catalogue · man unison(1) · home

On Copal: The catalogue's two-way sync, run when you choose -- for a laptop and a Pi that both change the same folder. Where rsync mirrors one way, unison merges both, and asks about conflicts.

unison [options]
unison root1 root2 [options]
unison profilename [options]

Use

Name two roots -- local folders, or one over ssh -- and unison compares them with what it saw last time, proposes what to copy each way, and asks about anything changed on both sides.

Examples

unison ~/docs ssh://pi//home/you/docssync, asking
unison -batch ~/docs ssh://pi//home/you/docsno questions: skip conflicts
unison -auto ~/docs /media/usb/docsaccept non-conflicts, ask the rest
unison workthe profile ~/.unison/work.prf

Options

-batch
ask nothing; conflicting files are skipped
-auto
accept the default actions, ask only about conflicts
-ui text
the text interface (the default here)
-path P
sync only P, within the roots
-ignore P
leave P out (as a pattern) -prefer ROOT on a conflict, take ROOT's version

Notes

  • Both machines need the same unison version -- 2.54 here -- or it refuses to talk.
  • The double slash in ssh://pi//home/you/docs is an absolute path; a single one would be relative to your home on pi.
  • A profile saves the roots and options: root = ... lines in ~/.unison/NAME.prf, then unison NAME.

See also rsync, syncthing, ssh

Smallweb

amfora A terminal browser for Gemini, with tabs, bookmarks and colour.

Smallweb · terminal program · amfora 1.11.0 · stage 12 · The application catalogue · home

On Copal: The catalogue's fullest Gemini browser for the terminal: tabs, bookmarks, subscriptions to feeds, and pages that look designed.

Use

Start it on an address, or open one with Space: the bottom bar takes a URL or a link number. Links are numbered on the page.

Examples

amforaits start page
amfora gemini://geminiprotocol.net/a capsule
Space (in amfora) the bottom bar: type a URL or a link number
1 2 3 ... follow link N
R reload
e edit the current URL
/ search the page

Options

URL
open it -v, --version the version

Notes

  • Every key is set, and can be changed, in ~/.config/amfora/config.toml, section [keybindings]; the defaults are listed there.
  • Web links open in a web browser as its config says; Gemini, Gopher over a proxy, and local files open in Amfora.

See also bombadillo, clagrange, gmnlm

bombadillo A browser for the small internet: Gopher, Gemini and Finger, with vi keys.

Smallweb · terminal program · bombadillo 2.4.0 · stage 12 · The application catalogue · man bombadillo(1) · home

On Copal: The catalogue's all-in-one smallweb browser: one program for the three protocols the small internet lives on, in a terminal.

bombadillo [options] [url]

Use

Open an address; links are numbered, and typing the number follows one. Commands start with :, as in vi. The web itself is not shown: web links can be handed to a web browser instead.

Examples

bombadilloits home page
bombadillo gemini://geminiprotocol.net/a Gemini capsule
bombadillo gopher://gopher.floodgap.coma Gopher hole
bombadillo finger://user@example.orga finger record
1 2 3 ... (in bombadillo) follow link N
j k scroll; g G top / bottom
b f back / forward
B bookmarks
q quit

Options

-t
set the terminal window's title to Bombadillo
-v
the version
-h
the usage

Notes

  • Settings are changed from inside with :set, and kept in ~/.config/bombadillo.
  • Gemini uses trust on first use: the first certificate a capsule shows is remembered, and a changed one is questioned.

See also amfora, clagrange, lynx, elinks

clagrange Lagrange in the terminal: the well-known Gemini browser, drawn with text.

Smallweb · terminal program · lagrange 1.21.1 · stage 12 · The application catalogue · home

needs sdl2, libcrypto3, fribidi, harfbuzz, mpg123-libs, libncursesw, opusfile, pcre2

On Copal: The catalogue's terminal build of Lagrange. The same package has lagrange, its window; clagrange is the one for a board without a desktop, or for use over SSH.

Use

Open addresses and files in tabs. It keeps Lagrange's features -- bookmarks, feeds, identities (client certificates) -- in a terminal. --dump prints a page as text and leaves, for scripts.

Examples

clagrangethe browser
clagrange gemini://geminiprotocol.net/open an address
clagrange a.gmi b.gmiseveral files, one tab each
clagrange --dump gemini://geminiprotocol.net/the page as text

Options

URL / PATH
open it; several open in tabs
-d, --dump
print the contents of the URLs to stdout and quit
-I, --dump-identity ID
with --dump: use this client certificate

Notes

  • Its settings, bookmarks and identities are Lagrange's, shared with the window version.
  • The window build, lagrange, is in the catalogue as its own row.

See also amfora, bombadillo, gmnlm

gemget Download files over Gemini, one URL or a list of them.

Smallweb · command-line tool · gemget 1.9.0 · stage 12 · The application catalogue · home

On Copal: The catalogue's Gemini downloader: wget's role, for saving pages, files or a list of them from capsules.

Use

Give it URLs; each is saved under its own name in the current folder, with a progress bar. -d chooses the folder, -o names a single file.

Examples

gemget gemini://example.org/file.txtsave one file
gemget -d ~/gemini gemini://a/x gemini://b/yseveral, into a folder
gemget -o index.gmi gemini://example.org/a page, under a chosen name
gemget -f urls.txt -d savedevery URL in a file
gemget -e gemini://example.org/dir/add .gmi to pages without one

Options

-o, --output PATH
the file name, for a single URL
-d, --directory DIR
the folder to save into
-f, --input-file FILE
read URLs from FILE, one a line
-e, --add-extension
add .gmi to pages that have no extension
-m, --max-size SIZE
skip anything larger
-q, --quiet
no progress bar
-i, --insecure
do not check the certificate

Notes

  • It fetches exactly the URLs given; it does not follow a page's links to mirror a whole capsule.

See also gmni, curl

gmni Fetch one Gemini page and print it -- Gemini's curl.

Smallweb · command-line tool · gmni 1.0 · stage 12 · The application catalogue · man gmni(1) · home

needs bearssl-libs

On Copal: The catalogue's Gemini tool for scripts: read a capsule into a pipe, save a file, or check what a server answers.

Use

Give it a URL; the page body goes to stdout. -i adds the response header, -L follows redirects, -o saves to a file.

Examples

gmni gemini://geminiprotocol.net/print a page
gmni -L gemini://example.org/oldfollow redirects
gmni -i gemini://example.org/with the status and meta line
gmni -o page.gmi gemini://example.org/save it
gmni -d 'search words' gemini://example.org/searchanswer an input prompt

Options

-L
follow redirects
-i
print the status and meta line too
-I
print only the status and meta line
-o PATH
write the response to PATH
-d INPUT
answer the server's input request with INPUT
-j MODE
trust on first use: always, once or fail

Notes

  • Gemini URLs need their scheme: gemini://, not just the host.
  • It shares gmnlm's trust store, so a capsule trusted in one is trusted in the other.

See also gmnlm, gemget, curl

gmnisrv Serve your own Gemini capsule from a folder.

Smallweb · command-line tool · gmnisrv 1.0 · stage 12 · The application catalogue · man gmnisrv(1) · home

needs mailcap, libcrypto3, libssl3

On Copal: The catalogue's Gemini server: publish a capsule from the Pi, with TLS certificates it makes for itself.

Use

Put .gmi pages in the folder the configuration names, start the service, and the capsule is at gemini://HOSTNAME/. The configuration is /etc/gmnisrv.ini: listen address, certificate store, and one section per host name.

Examples

doas mkdir -p /srv/geminithe default root for [localhost]
echo '# Hello from Copal' | doas tee /srv/gemini/index.gmi
doas rc-service gmnisrv startstart it
gmni gemini://localhost/see it
doas rc-update add gmnisrvat every boot

Options

-C PATH
another configuration file

Notes

  • Out of the box it listens on every address, port 1965, and serves only the host name localhost. For others to reach it, add a section named after the machine's host name, with its own root=.
  • Certificates are made on first use and kept in /var/lib/gemini/certs; clients remember them, so keep that folder.

See also gmni, amfora, darkhttpd

gmnlm A line-mode Gemini browser: print a page, read its numbered links, type a number.

Smallweb · terminal program · gmni 1.0 · stage 12 · The application catalogue · man gmnlm(1) · home

needs bearssl-libs

On Copal: The catalogue's plainest Gemini client, from the gmni package: no full screen, so it works in any terminal, a pipe or a slow link.

Use

It prints the page, pausing at each screenful, with the links numbered. At its prompt, a number follows a link and a few letters do the rest.

Examples

gmnlm gemini://geminiprotocol.net/open a capsule
gmnlm -W 72 gemini://example.org/wrap at 72 columns
3 (at the prompt) follow link 3
b f back / forward
m M save a bookmark / browse them
|less pipe the page into a program
q quit

Options

-W WIDTH
the width to wrap at
-j MODE
trust on first use: always, once or fail
-P
no paging

Notes

  • It trusts a capsule's certificate on first use and remembers it in ~/.local/share/gmni/known_hosts.
  • gmni is its companion for scripts: one page, no browsing.

See also gmni, amfora, bombadillo

System

btop A resource monitor with graphs: CPU, memory, disks, network and processes, live.

System · terminal program · btop 1.4.6 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · on the Copal Apps shelf · man btop(1) · home

On Copal: The store's richer htop: history graphs for every core, the disks and the network in one screen, with the mouse working throughout.

btop [-c file] [-d] [-f filter] [-l] [-p id] [-t] [-u ms] [--force-utf] [--themes-dir dir]

btop [--default-config | {-h | --help} | {-V | --version}]

Use

Start it; boxes show CPU, memory, disks, network and processes. Click or use the keys; Esc opens the menu with options and help. Numbers 1 to 4 toggle the boxes.

Examples

btopeverything
btop -p 1start with preset 1
btop -f firefoxprocesses filtered to firefox
btop -tplain console mode, 16 colours
btop -u 500update every half second
1 2 3 4 (in btop) show or hide cpu, memory, network, processes
f filter processes
k kill the selected process (asks first)
Esc q the menu / quit

Options

-p, --preset N
start with preset N (0-9)
-f, --filter TEXT
an initial process filter
-t, --tty
console mode: ANSI graph symbols, 16 colours
-l, --low-color
256 colours, no true colour
-u, --update MS
the update interval
-c, --config FILE
another config file

Notes

  • Its settings are saved from the menu to ~/.config/btop/btop.conf; btop --default-config prints the defaults.
  • On the Linux console (no desktop) -t gives graphs that draw correctly.

See also htop, copal-tm

busybox One small program that is three hundred commands: sh, sed, awk, vi, wget...

System · busybox 1.37.0 · Alpine's base system · man busybox(1) · home

On Copal: Alpine's base system is BusyBox, and so is Copal's. The fuller levels pull in GNU coreutils, grep and tar beside it, but sed, awk, find, xargs, vi, wget, ping, nc, ip, blkid and the shell /bin/sh stay BusyBox's.

Use

Mostly invisible: each applet is a link to /bin/busybox, and runs as whatever name it was called by. Call busybox by name to see what it provides, to read an applet's help, or to run the BusyBox version of a command a fuller package has replaced.

Examples

busybox --listevery applet it provides
ls -l $(command -v sed)-> /bin/busybox: sed is BusyBox here
busybox sed --helpan applet's options, and only those
busybox wget -O- https://example.com # the applet, even if GNU wget is in
apk info -W $(command -v find)BusyBox, or a real package?

Options

--list
the applets, one per line
APPLET --help
that applet's usage: the options it really has

Notes

  • The answers online are mostly for GNU. BusyBox applets take fewer options, and some take an option and ignore it: blkid -s UUID -o value prints the whole line and exits 0 -- it once put a device path where a UUID belonged in Copal's grub.cfg. Check with busybox APPLET --help.
  • /bin/sh is BusyBox ash, not bash: no arrays, no [[ ]] in scripts that start #!/bin/sh. Your login shell may be bash; scripts are not.
  • There is one manual page for all of it -- man busybox -- and each applet's section in it is short. --help is usually quicker.
  • Installing the GNU package (findutils, sed, gawk...) replaces the link; apk del puts BusyBox's back.

See also ip, logread, apk

delta A pager for git diffs: syntax colour, word-level changes, line numbers, side by side.

System · command-line tool · delta 0.19.2 · stage 12 · The application catalogue · home

needs libgit2, oniguruma

On Copal: The catalogue's diff viewer. Set as git's pager, it makes every git diff, show and log -p easier to read, in any terminal.

Usage: delta [OPTIONS] [MINUS_FILE] [PLUS_FILE]
Arguments:
  [MINUS_FILE]

Use

Set it once as git's pager, and git uses it for everything it pages. It also reads any diff from a pipe, or compares two files itself.

Examples

git config --global core.pager deltagit's pager, from now on
git config --global interactive.diffFilter 'delta --color-only'and in git add -p
git diffnow through delta
delta -s old.txt new.txttwo files, side by side
diff -u a b | deltaany unified diff

Options

-s, --side-by-side
the two versions in columns
-n, --line-numbers
line numbers down the side
--navigate
n and N jump between files in the pager
--dark / --light
for the terminal's background
--syntax-theme NAME
the colours; --list-syntax-themes lists them

Notes

  • Put settings in ~/.gitconfig under [delta]: side-by-side = true, line-numbers = true.
  • On Copal's light terminal theme, --light (or light = true in the config) keeps the colours readable.

See also git, tig, lazygit

dmesg Read the kernel's message buffer: hardware, drivers, and what went wrong.

System · dmesg 2.42.3 · stage 5 · Compressed swap in RAM (zram) · man dmesg(1) · home

needs libncursesw

On Copal: The first place to look when a device does nothing -- a USB radio that never appears, a card reader, a wifi chip without firmware. Copal's syslog does not collect kernel messages; they are only here.

dmesg [options]

dmesg --clear

dmesg --read-clear [options]

dmesg --console-level level

dmesg --console-on

dmesg --console-off

Use

Print what the kernel has said since boot, oldest first. Plug a device in, then look at the last lines: they say what it was recognised as, which driver took it, or why none did.

Examples

doas dmesg | tail -20the latest, after plugging something in
doas dmesg -Twith wall-clock times
doas dmesg -wfollow: print new lines as they come
doas dmesg -l err,warnerrors and warnings only
doas dmesg | grep -i usbeverything about USB

Options

-T, --ctime
human-readable timestamps (off after a suspend)
-H, --human
readable and paged, with colour
-w, --follow
wait for new messages
-W, --follow-new
print only new ones
-l, --level LIST
only these levels: emerg, alert, crit, err, warn, notice, info, debug
-k, --kernel
only kernel messages
--since TIME
only lines after TIME
-C, --clear
empty the buffer

Notes

  • It needs root on Copal: kernel.dmesg_restrict is 1, so without doas it says "read kernel buffer failed: Operation not permitted".
  • The buffer is fixed-size: on a long-running machine the boot messages have been overwritten. Look soon after the event.
  • Silence is an answer too. A device that adds no line at all is not being seen -- a cable, power, or (in a VM) a device not passed through.

See also logread, lsblk, rc-status

doas Run one command as root, or as another user.

System · doas 6.8.2 · stage 1 · Apply the setup-alpine answers · man doas(1) · home

On Copal: Copal's only way to root after stage 13 locks the root account. It is OpenBSD's small replacement for sudo; stage 1 installs it and makes your account an administrator by putting it in wheel.

doas [-Lns] [-C config] [-u user] command [args]

Use

Prefix a command that needs root. The rules in /etc/doas.conf and /etc/doas.d/*.conf say who may run what; Copal's say that anyone in wheel may run anything, and asks for the password once per session.

Examples

doas apk add htopone command as root
doas -sa root shell, for several
doas -u radbeeper ida command as another user
doas -C /etc/doas.confcheck a rule file for mistakes
doas -Lforget the remembered password now

Options

-s
run the shell from SHELL as the target user
-u USER
run as USER instead of root
-n
never ask: fail if the rule needs a password
-L
clear the remembered authentication (the persist rules)
-C FILE
parse FILE and report errors; with a command, say permit or deny

Notes

  • The LAST matching rule wins. Rule files in /etc/doas.d are read in alphabetical order -- setup-alpine writes 20-wheel.conf -- which is why Copal names its narrow no-password rules zz-copal-halt.conf and zz-radbeeper.conf: after the general wheel rule, so they match.
  • A new group takes effect at the next login. After adduser you wheel, log out and back in before doas will let you through.
  • sudo exists too: doas-sudo-shim turns the usual sudo spellings into doas, for scripts and habits that say sudo. There is no /etc/sudoers.
  • Always check an edited rule with doas -C FILE before logging out: a syntax error denies everything, and with root locked that means a rescue from another machine.

See also apk, rc-service

fastfetch The system at a glance, beside a logo: OS, kernel, CPU, memory, desktop, uptime.

System · command-line tool · fastfetch 2.64.2 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man fastfetch(1) · home

needs hwdata-pci

On Copal: The store's system summary: what this machine is, in one screen -- useful for a bug report, and the screenshot every desktop gets.

fastfetch [OPTIONS...]

Use

Run it; it prints the details beside Alpine's logo. A config file chooses which modules appear and in what order.

Examples

fastfetchthe summary
fastfetch -l nonewithout the logo (for a bug report)
fastfetch -c allevery module it has
fastfetch --gen-configwrite a config to edit
fastfetch --list-moduleswhat it can show

Options

-l, --logo NAME
another logo, or none
-c, --config FILE
a config file or preset (all, neofetch...)
--gen-config [PATH]
write a starting config
--list-modules
list the modules
-s, --structure LIST
which modules, in order: OS:Kernel:Memory

Notes

  • Its config is ~/.config/fastfetch/config.jsonc once generated.
  • It is neofetch's fast successor: the same idea, in C, in a fraction of the time.

See also neofetch, btop, uname

gitui A fast terminal interface for git, in tabs: status, log, files, stashes.

System · terminal program · gitui 0.28.1 · stage 12 · The application catalogue · home

needs libgit2, oniguruma, libssh2, libssl3

On Copal: The catalogue's other git interface: quick to start on large repositories, with every key it takes shown at the bottom.

Use

Start it in a repository. Tabs along the top -- Status, Log, Files, Stashing, Stashes -- switch with the number keys; the bar at the bottom lists the keys for the current view.

Examples

gituithe repository here
gitui -d ~/code/copal/.gitanother repository
1-5 (in gitui) switch tabs
Enter stage or unstage a file (Status)
c commit
Esc / q back / quit

Options

-d, --directory DIR
the git directory to open
-t, --theme FILE
a theme file from its config directory
-l, --logging
write a log (to find a problem)

Notes

  • Its key bindings and theme are files in ~/.config/gitui.
  • It does what git does: a push that needs a password or a key follows git's own settings.

See also git, lazygit, tig

htop An interactive process viewer: CPU, memory, and every process, live.

System · terminal program · htop 3.5.3 · stage 4 · X.Org, i3, a terminal and a browser · man htop(1) · home

needs lsof, libncursesw

On Copal: The task manager on Copal's i3 desktop, where Super+T opens it, and the first thing to run when a machine feels slow.

htop [-dCFhpustvH]
pcp-htop [-dCFhpustvH] [--host/-h host]

Use

The meters at the top show each core, memory and swap; the list below shows the processes, the busiest first. Keys along the bottom sort, search and filter the list.

Examples

htopeverything
htop -u $USERonly your processes
htop -tas a tree: which started which
htop -p 1234,5678only these process IDs
F3 F4 (in htop) search / filter
F5 tree view
F6 sort by a column
F10 quit

Options

-u USER
only USER's processes
-t, --tree
start in tree view
-p PIDS
only these processes
-d N
the update delay, in tenths of a second
-s COLUMN
sort by COLUMN

Notes

  • F2 is the setup screen: meters, columns and colours, saved to ~/.config/htop/htoprc.
  • Memory shown as "used" leaves out the page cache; a nearly full bar of cache is normal.

See also copal-tm, btop, rc-status

lazygit A terminal interface for git: stage, commit, branch, rebase and push from panels.

System · terminal program · lazygit 0.48.0 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · home

needs git

On Copal: The catalogue's git interface, and the one Copal's Neovim opens with Space g g, in a window over the editor.

Use

Start it in a repository. Panels on the left show status, files, branches, commits and stashes; the right shows what the selection is. Keys act on the selection, and the foot of the screen lists them.

Examples

lazygitthe repository here
lazygit -p ~/code/copalanother repository
lazygit -f README.mdthe history of one file
Space (in lazygit) stage or unstage the file
c commit the staged changes
P p push / pull
Tab / 1-5 move between panels
? every key here; q quit

Options

-p, --path DIR
the repository to open
-f, --filter PATH
only the history that touches PATH
-c, --config
print the default config
-cd, --print-config-dir
where its config lives

Notes

  • Its config is ~/.config/lazygit/config.yml; lazygit -c prints every setting with its default, to copy from.
  • Whatever it does is ordinary git: git log and git status in a shell show the same repository.

See also git, gitui, tig, nvim

lbu Save a RAM-resident Alpine system's changes to disk (the apkovl).

System · alpine-conf 3.22.0 · Alpine's base system · man lbu(8) · home

needs openrc

On Copal: Copal's first two stages run from RAM, the way Alpine boots from a card, and anything they change is gone at the next boot unless lbu commits it. Stage 3 moves the system onto the disk; after that, lbu has nothing to do.

lbu SUBCOMMAND [OPTIONS] [ARGS]

Use

On a diskless Alpine system, every file lives in RAM. lbu commit packs the changed configuration -- /etc and the list of installed packages, by default -- into an .apkovl.tar.gz on the boot medium, and the next boot unpacks it. On an installed Copal machine (every machine past stage 3) you will not need it.

Examples

lbu statuswhat changed since the last commit
lbu diffthe same, as a diff
doas lbu commit -dsave, and delete the older archive
doas lbu include /root/notes.txttrack a file outside /etc
lbu include -lwhat has been added to the set
lbu listevery file the next commit will pack

Options

commit, ci
write the apkovl to the medium
-d
with commit: remove the old apkovl first
-n
with commit: dry run, show what would be packed
status, st
changes since the last commit (A added, U updated, D deleted)
diff
the changes as a diff
include, add
add a file or directory to what is saved
exclude, ex
leave one out
list, ls
the files that would be packed
list-backup, lb
the older timestamped archives
revert REV
go back to one of them

Notes

  • Only /etc and apk's world are saved unless you lbu include more. A home directory in RAM is lost at every reboot.
  • The medium is LBU_MEDIA in /etc/lbu/lbu.conf -- the boot partition. Copal sets it from the partition it actually booted from (a Pi's mmcblk0p1, a PC's sda1, a VM's vda1).
  • df / says which kind of system this is: a disk partition means installed, and lbu does not apply; tmpfs means diskless, and it does.

See also setup-alpine, apk

logread Read BusyBox syslogd's in-memory log.

System · busybox 1.37.0 · Alpine's base system · man busybox(1) · home

a BusyBox applet: busybox logread --help, and BusyBox's page

On Copal: Alpine's usual answer to "where is the log" -- and on Copal the wrong one: Copal's syslogd writes the file /var/log/messages, not the in-memory buffer logread reads.

Use

On an Alpine system whose syslogd keeps a circular buffer in memory (started with -C), print it, or follow it. On Copal, read the file instead: the same messages, kept across reboots.

Examples

tail -50 /var/log/messagesCopal: the latest system messages
tail -f /var/log/messagesCopal: follow them
grep sshd /var/log/messagesone service's lines
logread -felsewhere: follow the buffer

Options

-f
follow: print new messages as they arrive
-F
the same, after printing the whole buffer first

Notes

  • On Copal logread answers "can't find syslogd buffer": syslogd runs with SYSLOGD_OPTS="-t" (see /etc/conf.d/syslog), which writes the file. That is expected, not a fault.
  • /var/log/messages belongs to the group wheel, so an administrator reads it without doas.
  • Kernel messages are not in it: read them with doas dmesg.

See also dmesg, rc-status, busybox

mkinitfs Build the initramfs: the small first root that finds and mounts the real one.

System · mkinitfs 3.14.1 · stage 10 · Wireless, audio, capture and disks · man mkinitfs(1) · home

needs apk-tools, busybox-binsh, kmod, lddtree, mdev-conf, libblkid, cryptsetup-libs, kmod-libs

On Copal: Every kernel install and upgrade runs it, through apk's trigger: setup-disk in stage 3, and each apk upgrade that brings a new kernel. You call it by hand only after changing what it includes.

mkinitfs [OPTIONS] [KERNELVERSION]

Use

Pack the kernel modules and tools needed to reach the root filesystem -- the disk controller, the filesystem, USB -- into /boot/initramfs-*. Which ones is set by features= in /etc/mkinitfs/mkinitfs.conf. Add a feature, then rebuild.

Examples

cat /etc/mkinitfs/mkinitfs.confthe features this machine uses
mkinitfs -Levery feature there is
mkinitfs -l | lessdry run: the files it would pack
doas mkinitfsrebuild for the running kernel
ls /lib/modulesthe kernel versions installed

Options

KERNELVERSION
build for that kernel (a name in /lib/modules); default the running one
-L
list the available features
-l
dry run: list the files it would include
-F FEATURES
use these features instead of the config's
-o FILE
write to FILE instead of /boot
-c FILE
read another config file
-C ALGORITHM
compress with gzip (default), xz, zstd, lz4 or none

Notes

  • A root on something the features do not name -- NVMe, LVM, an encrypted disk -- boots to "mounting root failed" and an emergency shell. Add nvme, lvm or cryptsetup to features= and rebuild before rebooting onto it.
  • After a kernel upgrade, reboot soon: the running kernel's modules have been replaced, so loading a new module fails until you do.
  • "WARNING: no kernel found" during stage 3 is expected: setup-disk runs on the RAM system, which has no kernel package of its own.

See also apk, lsblk

neofetch The original system-summary-with-a-logo script.

System · command-line tool · neofetch 7.1.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man neofetch(1) · home

needs bash

On Copal: The store keeps it for the recipes and screenshots that name it; fastfetch is its faster successor and the one to use day to day.

neofetch func_name --option "value" --option "value"

Use

Run it; it prints the system's details beside an ASCII logo. It is a bash script, so it is slower than fastfetch, and no longer developed.

Examples

neofetchthe summary
neofetch --offno logo
neofetch --ascii_distro archanother distribution's logo
neofetch --config noneignore any config file

Options

--off
no ASCII art
--ascii_distro NAME
use that distribution's logo
--config FILE
another config file; none for the defaults
--backend NAME
how to show an image (ascii, off...)

Notes

  • Upstream stopped in 2020: details of newer hardware and desktops may be missing or wrong. fastfetch reports them correctly.
  • It comes from Alpine's testing repository (neofetch@testing).

See also fastfetch

setup-alpine Alpine's installer: keyboard, hostname, network, time, users, sshd, disk.

System · alpine-conf 3.22.0 · Alpine's base system · man setup-alpine(8) · home

needs openrc

On Copal: Stage 1 runs it with an answer file that copal-prep.sh wrote on the Mac, so the first boot asks almost nothing. Copal gives it no disk (DISKOPTS=none): stage 3 installs to disk itself.

setup-alpine [-ahq] [-c FILE | -f FILE]

Use

Run once on a new Alpine system. It calls a family of smaller scripts in turn -- setup-keymap, setup-interfaces, setup-timezone, setup-user, setup-sshd and the rest -- and those are the useful part afterwards: each one redoes a single step on a machine already running.

Examples

doas setup-interfacesredo the network, wifi included
doas setup-timezonechange the time zone
doas setup-keymapchange the keyboard layout
doas setup-apkreposchoose another package mirror
setup-alpine -c answers.txtwrite a blank answer file, change nothing
cat /media/*/answers.txtthe answers Copal's stage 1 used

Options

-f FILE
install from an answer file (a path or a URL)
-c FILE
write an answer file template and stop
-q
quick: hostname, networking and a mirror, nothing else
-e
set an empty root password (implied by -q)
-a
write an apkovl only; install nothing to disk

Notes

  • An answer file is a shell script it sources: KEYMAPOPTS, HOSTNAMEOPTS, INTERFACESOPTS, USEROPTS, DISKOPTS and so on. There is no variable for the root password; Copal answers that prompt itself.
  • Run over SSH, it leaves the network running while it rewrites the settings, so the connection you are using is not cut from under you.
  • The other setup scripts are in /usr/sbin: ls /usr/sbin/setup-*. Each has its own man page: man setup-interfaces.

See also lbu, doas, wpa_passphrase

sha224sum Compute or check SHA-224 checksums; its siblings do MD5 and the other SHA sizes.

System · command-line tool · coreutils 9.11 · stage 12 · The application catalogue · man sha224sum(1) · home

needs coreutils-env, coreutils-fmt, coreutils-sha512sum, acl-libs, libattr, libcrypto3, utmps-libs

On Copal: The catalogue's row for GNU coreutils' checksum tools: prove a download or a copied file is exactly what it should be. Copal's own downloads are checked against sha256 sums the same way.

sha224sum [OPTIONS] [FILE]...

Use

Give it files and it prints a checksum for each. Save those lines to a file, and -c later checks the files against it. sha256sum is the one most downloads publish; md5sum, sha1sum and sha512sum work alike.

Examples

sha224sum photo.jpgone checksum
sha256sum alpine.isothe size most downloads publish
sha256sum *.iso > SUMSsave checksums for later
sha256sum -c SUMScheck the files against them
echo 'HASH file.iso' | sha256sum -c # check against a published hash

Options

-c, --check
read checksums from a file and check them
--quiet
with -c: print only failures
--status
with -c: print nothing; the exit code says
-b, --binary
read in binary mode (the same on Linux)

Notes

  • The line format is the hash, two spaces, then the file name; -c needs exactly that.
  • MD5 and SHA-1 catch accidents, not tampering. For checking a download's authenticity, use SHA-256 or longer.

See also curl, rsync

tig A text-mode browser for git history: the log, each commit's diff, blame.

System · terminal program · tig 2.6.1 · stage 12 · The application catalogue · man tig(1) · home

needs git, libncursesw, pcre2

On Copal: The catalogue's git history reader: faster than scrolling git log -p, and its blame view walks back through a line's past.

tig        [options] [revisions] [--] [paths]
tig log    [options] [revisions] [--] [paths]
tig show   [options] [revisions] [--] [paths]
tig reflog [options] [revisions]
tig blame  [options] [rev] [--] path
tig grep   [options] [pattern]
tig refs   [options]
tig stash  [options]
tig status
tig <      [Git command output]

Use

With no arguments it lists the commits; Enter opens one's diff in a split below. It takes the same arguments as git log, and has views for blame, status and refs.

Examples

tigthe log
tig README.mdcommits that touched one file
tig blame src/main.cwho changed each line
tig statusstage and unstage, like git add -p
tig --allevery branch
Enter (in tig) open the selection
j k move; q back, or quit
/ search

Options

blame FILE
the blame view
status
the status view
refs
branches and tags
--all
every ref, not just the current branch
PATH
only commits touching PATH

Notes

  • In the blame view, a comma on a line moves blame to the commit before it: the way to follow a line back.
  • Settings go in ~/.tigrc (or ~/.config/tig/config).

See also git, lazygit, gitui, delta

Terminals

abduco Detach and reattach any terminal program -- sessions without a multiplexer.

Terminals · command-line tool · abduco 0.6 · stage 12 · The application catalogue · man abduco(1) · home

On Copal: The catalogue's smallest session keeper: it does one thing tmux does -- keep a program running when the terminal goes -- and nothing else, so it pairs with dvtm or any single program.

abduco [-e detachkey] [-r] [-f] -c name command [args ...]
abduco [-e detachkey] [-r] [-f] -n name command [args ...]
abduco [-e detachkey] [-r] [-f] [-l] -A name command [args ...]
abduco [-e detachkey] [-r] [-l] -a name

Use

-c NAME CMD starts a program in a named session; Ctrl-\ detaches; -a NAME reattaches. With no arguments it lists the sessions.

Examples

abduco -c build make -j4run a build in session "build"
abducothe sessions, and whether they are attached
abduco -a buildback into it
abduco -A work dvtmattach, or create it running dvtm
abduco -n logs tail -f /var/log/messagesstart one detached

Options

-c NAME CMD
create a session running CMD and attach
-n NAME CMD
create it detached
-a NAME
attach to it
-A NAME CMD
attach, or create if it does not exist
-e KEY
the detach key (default ^\)
-r
read-only: watch without typing

Notes

  • Ctrl-\ is the detach key; the program keeps running.
  • It keeps no screen contents: reattaching shows what the program draws next. A full-screen program redraws; a plain shell shows only new output.

See also dtach, dvtm, tmux

byobu A friendlier face on tmux: function-key shortcuts and a status bar of system facts.

Terminals · terminal program · byobu 6.16 · stage 12 · The application catalogue · man byobu(1) · home

needs python3, tmux, py3-newt

On Copal: The catalogue's easy multiplexer: tmux underneath, but F2 for a new window and F6 to detach, with no prefix key to learn.

byobu [options]

byobu-screen [screen options]

byobu-tmux [tmux options]

Options to byobu are simply passed through screen(1) or tmux(1).

Use

Run byobu and work as in tmux; the function keys do the common things, and the status line along the bottom shows load, memory and the clock. Sessions persist and reattach, as tmux's do.

Examples

byobustart or reattach
byobu new -s worka named session (tmux's options pass through)
byobu lsthe sessions
F2 (inside) a new window
F3 F4 previous / next window
F6 detach
F8 rename the window
F9 the configuration menu

Options

Notes

  • "locale: not found" at start is harmless: byobu asks for the character map with a locale command that musl systems do not have.
  • Function keys that the terminal or desktop keeps for itself (F11 for full screen, F10 in some terminals) do not reach it; F9 lets you switch to Ctrl-a keys instead.
  • Its settings live in ~/.byobu.

See also tmux, screen

dtach Keep a program running detached from the terminal, reached through a socket file.

Terminals · command-line tool · dtach 0.9 · stage 12 · The application catalogue · man dtach(1) · home

On Copal: The catalogue's oldest and smallest session keeper, abduco's ancestor: a program behind a socket you can leave and come back to.

dtach -a <socket> <options>
dtach -A <socket> <options> <command...>
dtach -c <socket> <options> <command...>
dtach -n <socket> <options> <command...>
dtach -N <socket> <options> <command...>
dtach -p <socket>

Use

Name a socket file and a command. -c creates the session and attaches, -a reattaches, and Ctrl-\ detaches.

Examples

dtach -c /tmp/build.sock make -j4start, attached
dtach -a /tmp/build.sockreattach later
dtach -A /tmp/ed.sock nvim notes.mdattach, or start it if not running
dtach -n /tmp/srv.sock ./serverstart detached

Options

-c SOCK CMD
create a session and attach
-n SOCK CMD
create it detached
-a SOCK
attach
-A SOCK CMD
attach, or create if it does not exist
-e CHAR
the detach character (default ^\)
-E
no detach character at all
-r METHOD
how to redraw on attach: none, ctrl_l or winch

Notes

  • The socket is an ordinary file path: anyone who can open it can attach, so keep it in a folder only you can read, not a shared /tmp in a multi-user machine.
  • Like abduco, it keeps no screen: -r winch asks a full-screen program to redraw when you attach.

See also abduco, screen, tmux

dvtm A tiling window manager for the terminal: several shells arranged side by side, dwm-style.

Terminals · terminal program · dvtm 0.15_git20210309 · stage 12 · The application catalogue · man dvtm(1) · home

needs ncurses-terminfo, libncursesw

On Copal: The catalogue's smallest way to split a terminal: panes laid out automatically, as dwm lays out windows. It does not detach by itself; with abduco, it does.

dvtm [-v] [-M] [-m modifier] [-d delay] [-h lines] [-t title] [-s status-fifo] [-c cmd-fifo]
     [command ...]

Use

Start it; Ctrl-g is the prefix. Ctrl-g c opens another shell, and the layout tiles them: one large on the left, the rest stacked on the right.

Examples

dvtmstart, with one shell
dvtm htop 'watch -n2 df -h'start with these programs in panes
abduco -c work dvtma detachable dvtm session
Ctrl-g c (inside) a new shell
Ctrl-g j / k next / previous pane
Ctrl-g Space the next layout
Ctrl-g q q quit

Options

-m MOD
another prefix key: -m ^b for Ctrl-b
-M
mouse support on
-d DELAY
Escape delay, in milliseconds
-h LINES
scrollback lines per pane
-t TITLE
the terminal title
CMD...
start with these commands in panes

Notes

  • To keep a session when the terminal closes, run it inside abduco (as above) and reattach with abduco -a work.
  • Ctrl-g is also a key some programs want; -m moves the prefix.

See also abduco, tmux, zellij

pwsh PowerShell: Microsoft's shell and scripting language, passing objects between commands.

Terminals · terminal program · powershell 7.6.1 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs dotnet10-runtime, libpsl-native

On Copal: The store's PowerShell, as on Windows: for scripts written for it, for managing Windows and cloud systems from the Pi, and for learning it where it is used at work.

Use

Start it for its prompt, or run a script or one command. Its commands are Verb-Noun (Get-ChildItem, Get-Process) and pass objects, not text: a pipeline sorts and filters by property.

Examples

pwshthe prompt; exit to leave
pwsh -File script.ps1run a script
pwsh -c 'Get-Process | Sort-Object CPU -Descending | Select-Object -First 5'
pwsh -NoProfile -c '$PSVersionTable' # the version, without your profile
Get-Help Get-ChildItem -Examples (at the prompt) examples for a command
Get-Command *Item* commands matching a word

Options

-File FILE
run a script
-Command CMD
run CMD (-c)
-NoProfile
skip the profile scripts
-NoLogo
no banner
-Login
start as a login shell

Notes

  • Linux commands still work inside it, but they pass text: ls | Sort-Object sorts lines, not files. Get-ChildItem gives objects.
  • Its telemetry is off only with POWERSHELL_TELEMETRY_OPTOUT=1 set in the environment before it starts.
  • Not on ARMv6 or 32-bit x86: its row is gated off there.

See also dotnet, bash

screen GNU Screen: terminal sessions that survive disconnection, with windows inside one terminal.

Terminals · terminal program · screen 5.0.2 · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man screen(1) · home

needs libncursesw, linux-pam

On Copal: The catalogue's original multiplexer, beside tmux: on nearly every Unix, and still the one many guides and serial-console recipes use -- screen /dev/ttyUSB0 115200 is a serial terminal.

screen [ -options ] [ cmd [ args ] ]
screen -r [[pid.]tty[.host]]
screen -r sessionowner/[[pid.]tty[.host]]

Use

Start a session, run programs in its windows, detach with Ctrl-a d, and reattach later -- from this machine or over SSH. Every key starts with the prefix Ctrl-a.

Examples

screen -S builda named session
screen -lsthe sessions running
screen -r buildreattach
screen -d -r buildreattach, detaching it elsewhere first
screen /dev/ttyUSB0 115200a serial console at 115200 baud
Ctrl-a d (inside) detach
Ctrl-a c a new window; Ctrl-a n / p next / previous
Ctrl-a [ scrollback: move with the arrows, Esc to leave
Ctrl-a ? every key

Options

-S NAME
name the new session
-ls
list sessions
-r [NAME]
reattach
-d -r
detach elsewhere, then reattach here
-x
attach without detaching (share the session)
-L
log the window to screenlog.0

Notes

  • A serial device needs the group dialout; leave a serial session with Ctrl-a k.
  • tmux is Copal's default multiplexer (stage 7); screen is here for the habits and recipes that name it.

See also tmux, byobu, abduco

zellij A terminal workspace: panes, tabs and floating windows, with its keys shown on screen.

Terminals · terminal program · zellij 0.42.2 · stage 12 · The application catalogue · man zellij(1) · home

needs libcrypto3, libssl3

On Copal: The catalogue's modern multiplexer: tmux's detachable sessions, but every key it takes is listed at the bottom, so nothing needs to be learned first.

Use

Start it and work in panes and tabs. The bar at the bottom shows the modes -- Ctrl-p for panes, Ctrl-t for tabs, and so on -- and inside each mode the keys it offers. Sessions survive a detach and reattach by name.

Examples

zellija new session
zellij -s worka named one
zellij lsthe sessions
zellij attach workback into it
zellij kill-session workend it
Ctrl-p n (inside) a new pane; Ctrl-p d one below
Ctrl-t n a new tab
Ctrl-o d detach
Ctrl-q quit, ending the session

Options

-s, --session NAME
name the new session
attach NAME
attach to a session (a)
list-sessions
list them (ls)
kill-session NAME
end one (k)
options
change behaviour for this run

Notes

  • Its Ctrl keys can clash with programs inside it (Ctrl-p in a shell's history, Ctrl-o in nano); Ctrl-g locks them so everything passes through, and Ctrl-g again unlocks.
  • Configuration is ~/.config/zellij/config.kdl; zellij setup --dump-config prints the default to start from.

See also tmux, screen, byobu

Tools

ollama Run large language models locally: download a model, then chat with it or call it from programs.

Tools · command-line tool · ollama 0.17.7 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

On Copal: The store's local AI, on the 64-bit boards: small models run on a Pi 5's CPU, offline, with nothing sent anywhere.

Usage:
  ollama [flags]
  ollama [command]

Use

Start the server, then pull a model and run it. The server stays running and answers programs on port 11434; ollama run gives a chat prompt.

Examples

ollama serve &start the server (no service is installed)
ollama pull llama3.2:1ba small model, about 1.3 GB
ollama run llama3.2:1bchat; /bye to leave
ollama listthe models downloaded
ollama pswhich are loaded, and in what memory
ollama rm llama3.2:1bfree the space

Options

serve
start the server
pull MODEL
download a model
run MODEL
chat with it (pulls it first if needed)
list
the downloaded models
ps
the running ones
stop MODEL
unload one
rm MODEL
delete one

Notes

  • Models are large: each is gigabytes, kept in ~/.ollama/models. On a small card, one small model is the budget.
  • Speed depends on memory: a model bigger than free RAM swaps and crawls. On a 4 GB Pi, 1B to 3B models are the practical size.
  • 64-bit boards only: its row is gated to aarch64 and x86_64.

See also python3, curl

scrcpy Show and control an Android phone on the desktop, over USB or Wi-Fi, through adb.

Tools · command-line tool · scrcpy 4.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man scrcpy(1) · home

needs android-tools, sdl3, ffmpeg-libavcodec, ffmpeg-libavdevice, ffmpeg-libavformat, ffmpeg-libavutil, ffmpeg-libswresample, libusb

On Copal: The store's phone mirror: the phone's screen in a window, typed on with the keyboard, its sound on the Pi's speakers -- nothing installed on the phone.

scrcpy [options]

Use

Turn on USB debugging on the phone (Developer options), plug it in and accept the prompt on the phone, then run scrcpy. The phone's screen opens in a window; the mouse and keyboard control it.

Examples

adb devicesis the phone seen and authorised?
scrcpymirror and control it
scrcpy -m 1024a smaller picture, for a slower board
scrcpy --no-audiopicture only
scrcpy -ea phone connected over Wi-Fi (adb tcpip)
scrcpy --record=phone.mp4record the screen while mirroring

Options

-m, --max-size=N
limit the longer side to N pixels
-b, --video-bit-rate=R
the video bit rate
--no-audio
no sound forwarding
-s, --serial=ID
choose a phone when several are connected
-e, --select-tcpip
use the phone connected over TCP/IP
--record=FILE
record while mirroring

Notes

  • "adb: no permissions" means the phone's USB device is not yours: the Android udev rules (an optional of scrcpy) give it to plugdev, and copal-store access adds you to that group.
  • The first connection must be accepted on the phone: "Allow USB debugging?".

See also waydroid, adb

scrot Take a screenshot on an X11 desktop: the screen, a window, or a region.

Tools · command-line tool · scrot 2.0.0 · stage 12 · The application catalogue · man scrot(1) · home

needs imlib2, libx11, libxcomposite, libxfixes, libxrandr

On Copal: The screenshot tool for Copal's i3 desktop, which runs on X11. On the Hyprland desktop (Wayland) it cannot see the screen: there, Super+Shift+S (copal-shot) and grim do the job.

scrot [-bcfhimopuvz] [-a X,Y,W,H] [-C NAME] [-D DISPLAY] [-d SEC] [-e CMD]
      [-k OPT] [-l STYLE] [-M NUM] [-n OPTS] [-q NUM] [-s OPTS] [-t % | WxH]
      [-w NUM] [[-F] FILE]

Use

With no arguments it saves the whole screen as a PNG in the current folder, named by the date and time. -s lets you drag out a region, -u takes the focused window, -d waits first.

Examples

scrotthe whole screen, into this folder
scrot ~/Pictures/%Y-%m-%d-%H%M%S.png # to a named file
scrot -sdrag out a region
scrot -u -d 3the focused window, after 3 seconds
scrot -e 'mv $f ~/Pictures/'run a command on the saved file

Options

-s, --select
choose a region, or click a window
-u, --focused
the focused window
-d, --delay SEC
wait SEC seconds first
-c, --count
show a countdown with -d
-p, --pointer
include the mouse pointer
-e, --exec CMD
run CMD on the saved image ($f is its name)
-q, --quality N
image quality, 1-100

Notes

  • On Wayland it saves a black or empty picture, or fails: it asks the X server for the screen, which only holds X programs. Use grim (the whole screen), grim -g "$(slurp)" (a region) or Super+Shift+S.
  • %Y, %m and the other date codes in the file name come from strftime.

See also copal-shot, tesseract

tldr Short, practical examples for a command: the man page's answer to "just show me how".

Tools · command-line tool · tealdeer 1.8.0 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · home

needs libcrypto3, libssl3

On Copal: The store's quick reference (tealdeer): a handful of examples per command, for when a man page is too long -- the Terminal Guide's spirit, for commands it does not cover.

Usage: tldr [OPTIONS] [COMMAND]...
Arguments:
  [COMMAND]...  The command to show (e.g. `tar` or `git log`)

Use

Fetch the pages once with --update; then tldr COMMAND prints its examples. The cache is local, so it works offline afterwards.

Examples

tldr --updatefetch the pages (first, and now and then)
tldr tarexamples for tar
tldr -p linux ipthe Linux page when platforms differ
tldr --list | wc -lhow many pages there are

Options

-u, --update
refresh the local page cache
-l, --list
list every command with a page
-p, --platform P
linux, osx, windows, common
-L, --language L
pages in another language

Notes

  • Right after install there is no cache: every page says it is missing until tldr --update has run once, with a network.
  • The pages are written for GNU/Linux: an option BusyBox lacks will fail here. The man page (or this guide) says what the installed version takes.
  • It comes from Alpine's testing repository (tealdeer@testing).

See also man, apropos

tmux Several shells in one terminal, and sessions that outlive the connection.

Tools · terminal program · tmux 3.7c · stage 7 · Compilers, editors, Claude Code and the ~/code checkouts · man tmux(1) · home

needs libevent, libncursesw

On Copal: Stage 7 installs it for work over SSH: a build or an install left running in tmux survives the laptop closing, and a Pi with no desktop gets split panes on its one console.

tmux [-2CDhlNuVv] [-c shell-command] [-f file] [-L socket-name] [-S socket-path] [-T features]
     [command [flags]]

Use

Start a session, run things in its windows and panes, detach, and attach again later -- from the same machine or over SSH from another. Every key starts with the prefix, Ctrl-b.

Examples

tmuxa new session
tmux new -s builda new session called build
tmux attach -t buildback into it, from anywhere
tmux lsthe sessions running
tmux kill-session -t buildend one

Options

Ctrl-b d
detach: the session keeps running
Ctrl-b c
a new window
Ctrl-b %
split into left and right panes
Ctrl-b "
split into top and bottom panes
Ctrl-b z
zoom the pane to the full window, and back
Ctrl-b [
copy mode: scroll back with the arrows, q to leave
Ctrl-b s
choose a session from a list
Ctrl-b ?
every key binding

Notes

  • Scrolling with the mouse wheel shows the terminal's scrollback, not the pane's, until set -g mouse on is in ~/.tmux.conf (or ~/.config/tmux/tmux.conf). Copal writes no tmux config: these are tmux's defaults.
  • A session survives a lost SSH connection, not a reboot.
  • Inside Neovim, Escape feels slow under tmux: set -sg escape-time 10 in the config fixes it.

See also ssh, abduco

x11vnc Share a running X11 desktop over VNC, so another machine can see and control it.

Tools · terminal program · x11vnc 0.9.17 · stage 12 · The application catalogue · man x11vnc(1) · home

needs libx11, libxdamage, libxext, libxfixes, libxi, libxinerama, libxrandr, libxtst

On Copal: The catalogue's screen sharing for Copal's i3 desktop (X11): help someone at the Pi from your Mac, with a VNC viewer. It shares the session already on screen rather than starting a new one.

x11vnc [OPTION]...

Use

Run it inside the X session you want to share; it listens on port 5900. Connect with a VNC viewer -- macOS has one built in: vnc://pi in Finder's Connect to Server. Set a password first, and prefer an SSH tunnel to the open port.

Examples

x11vnc -storepasswdset a password (in ~/.vnc/passwd)
x11vnc -rfbauth ~/.vnc/passwd -display :0 -forever
x11vnc -localhost -rfbauth ~/.vnc/passwd -display :0only through a tunnel
ssh -L 5900:localhost:5900 pithe tunnel, from the other machine

Options

-display :0
the X display to share
-rfbauth FILE
require the password stored in FILE
-storepasswd
store a VNC password
-localhost
accept only local connections (use an SSH tunnel)
-forever
keep serving after a viewer disconnects
-shared
allow several viewers at once
-viewonly
viewers can watch, not control

Notes

  • It shares X11 only. The Hyprland desktop is Wayland, where it sees nothing useful; share the i3 session, or reach the Pi over SSH.
  • Without -rfbauth, anyone who can reach port 5900 gets the desktop. With -localhost and an SSH tunnel, only someone who can log in by SSH can.

See also ssh, orrery

Transfer

httrack Copy a website to disk, links rewritten, so it can be read offline.

Transfer · command-line tool · httrack 3.49.21 · stage 18 · The Copal Store, and OpenShot compiled · on the Copal Apps shelf · man httrack(1) · home

needs httrack-doc, pkgconfig, libcrypto3, libssl3, zlib

On Copal: The store's website copier: save a manual, a reference site or your own old site as a folder of files a browser opens from disk.

httrack [ url ]... [ -filter ]... [ +filter ]...  [ -O, --path ] [ -w, --mirror ] [ -W,
--mirror-wizard ] [ -g, --get-files ] [ -i, --continue ] [ -Y, --mirrorlinks ] [ -P, --proxy
] [ -%f, --httpproxy-ftp[=0] ] [ -%b, --bind ] [ -rN, --depth[=N] ] [ -%eN, --ext-depth[=N] ]
[ -mN, --max-files[=N] ] [ -MN, --max-size[=N] ] [ -EN, --max-time[=N] ] [ -AN,
--max-rate[=N] ] [ -%cN, --connection-per-second[=N] ] [ -%G, --pause ] [ -GN,
--max-pause[=N] ] [ -cN, --sockets[=N] ] [ -TN, --timeout[=N] ] [ -RN, --retries[=N] ] [ -JN,
--min-rate[=N] ] [ -HN, --host-control[=N] ] [ -%P, --extended-parsing[=0] ] [ -n, --near ] [
-t, --test ] [ -%L, --list ] [ -%S, --urllist ] [ -%m, --sitemap ] [ -NN, --structure[=N] ] [
-%N, --delayed-type-check[=N] ] [ -%D, --cached-delayed-type-check[=0] ] [ -%M,
--mime-html[=0] ] [ -%Z, --single-file[=0] ] [ -LN, --long-names[=N] ] [ -KN,
--keep-links[=N] ] [ -x, --replace-external ] [ -%x, --disable-passwords[=0] ] [ -%q,
--include-query-string[=0] ] [ -%g, --strip-query ] [ -%C, --host-alias ] [ -o,
--generate-errors[=N] ] [ -X, --purge-old[=0] ] [ -%p, --preserve ] [ -%T,
--utf8-conversion[=0] ] [ -bN, --cookies[=N] ] [ -%K, --cookies-file ] [ -%Y, --why ] [ -u,
...

Use

Give it the address and a folder with -O; it follows links within the site, saves the pages and their images, and rewrites the links to point at the local copies. Limit the depth, or it may try to copy far more than you meant.

Examples

httrack https://example.org/docs/ -O ~/mirror/docscopy a site's section
httrack https://example.org/ -O ~/mirror/site --depth=3three links deep at most
httrack https://example.org/ -O ~/mirror/site --max-rate=100000at most 100 kB/s
httrack --update -O ~/mirror/docsrefresh an earlier copy

Options

-O, --path DIR
where the copy goes
--depth=N
how many links deep to follow
--ext-depth=N
how far into other sites (default 0: none)
--max-rate=N
bytes per second, at most
--sockets=N
parallel connections (default 4)
--update
update a copy made before
-v, --verbose
log on screen

Notes

  • Be kind to the site: a limited depth and a modest --max-rate; copy only what you are allowed to.
  • It does not run JavaScript: a site built by script copies as empty pages.
  • It comes from Alpine's testing repository (httrack@testing).

See also curl, lftp