A macOS shell tool that bulk-erases external USB disks and copies audio content onto them in parallel.
This document is for engineers and power users deciding whether the script is safe to run, audit, or re-publish. It describes exactly what the script does, how it works, the safety guards and the reasoning behind them, what it deliberately does not do, and the licensing.
The tool provisions many identical USB audio-player devices (e.g. MegaVoice or any player that reads a FAT filesystem) in one operation: it erases each selected external disk, writes a fresh full-size FAT32 partition, and copies a folder of audio content onto every device in parallel. It is operated by non-technical field users through native macOS dialogs; the terminal output is the authoritative record.
The loader does not need to live in the content folder: at start-up it asks the operator to
choose the content folder (a native choose folder dialog, defaulting to the Desktop),
then copies that folder's contents (minus any helper files) to each device. Keeping the loader
beside the content still works — just pick that folder. This fills the same role as Hope Tech
Global's HTGv4.CMD on Windows.
display notification requires 10.9, and that call is best-effort). The APFS source-disk
resolution (§5) is fully exercised on 10.13+; on older HFS+ systems the APFS step simply finds
nothing and the physical-disk walk still resolves the source correctly./bin/bash (bash 3.2, the version Apple ships). The script
re-execs itself under /bin/bash if launched with sh/zsh or in POSIX mode.diskutil,
osascript, cp, touch, sort, dd, sync,
dot_clean, defaults, scutil, df,
du, find, mktemp, pkill, sed/awk.sudo / no root. All disk operations go through diskutil
(which uses macOS's privileged Disk Arbitration service without a password). The script never
escalates privileges.For every disk the operator selects, the script runs
diskutil eraseDisk FAT32 <LABEL> MBRFormat /dev/diskN. This wipes the
entire physical disk — every partition and every volume on it — and writes a new
MBR partition map with a single full-size FAT32 volume. Selection is at the level of whole physical
disks, never individual partitions.
/bin/bash if not already running there.Load Audio Players.applescript) that the operator double-clicks and Runs in
Script Editor; it resolves its own folder via path to me, verifies
load_content.sh is present — beside it, or (in the download disk image) in a hidden
.loader/ sub-folder next to it, so the DMG window shows only the launcher and a
non-technical operator cannot pick the wrong file — and issues
tell application "Terminal" to do script "/bin/bash <loader>" —
so the whole run happens in a real Terminal/TTY (live progress bar, colours, prompts, signal traps),
identical to the manual drag-onto-Terminal path which remains the fallback. The wrapper is a
script document, not an app bundle, so a downloaded copy is not Gatekeeper-blocked. The
first-run prompts are the one-time "control Terminal" automation consent and — when run from
the read-only DMG — a benign Script Editor "file is locked" notice the operator simply
cancels (running, not editing, needs no unlock). Both launcher and loader are excluded from the
device payload. The window runs the loader via exec, so on completion no shell process
lingers (the window reads [Process completed]) and quitting Terminal never triggers the
“terminate the running process?” prompt.choose folder dialog (osascript, defaulting to the Desktop) asks which folder holds
the content; the loader copies that folder's contents. A folder path may instead be passed as the
first argument — how the run-again restart reuses the same folder without re-prompting —
and text/SSH mode accepts a typed path. In firmware-update mode
(--firmware, terminal-only) this step instead selects a single firmware file.PLAYER); input
is sanitized to [A-Za-z0-9], uppercased, truncated to 11 chars. REDO is reserved.001…,
files 001.mp3… with extension preserved; one counter per directory covers folders and
files together, restarting in each directory; the source is untouched). Children of a renamed folder
are written under its renamed path.<details> folder tree in play order, original names alongside renamed device names,
Expand/Collapse-all controls. Items flagged by the content check carry their specific reason inline;
every ancestor folder of a flagged item is marked and pre-expanded, and the page opens automatically
when anything is flagged. The tree is re-keyed (/ → byte 2, folders
keyed just below their children) so a subtree is always contiguous even around prefix-named siblings
(A / A extra); the manifest itself stays in true write order. The same
preview is available on demand from the erase confirmation's Preview order… button
(a failed open is contained and never aborts the confirmation), and text-mode runs (SSH)
print the tree directly in the Terminal instead of opening a browser. In the erase dialog, Cancel
folds into Back (3-button limit): Esc = Back, the re-shown disk list keeps the operator's previous
selection, and the list's own Cancel aborts the run.Secure Digital, or USB for USB-wired internal readers) — an internal
SSD/HDD can never qualify (Apple Fabric / PCI-Express / SATA, not removable), and APFS synthesized
containers are virtual, outside the physical listing. Skips the source disk(s) and any
write-protected (read-only) media, e.g. an SD card with its lock slider set. Captures each disk's
exact byte size for later re-checks..DS_Store
writes to USB volumes (the pre-run value is captured first and restored on exit — §9). The
source folder itself is never modified.tell application "Terminal" to activate, GUI only) so the progress
bar is visible rather than buried behind the write-order preview or other windows — not looped, so
the operator can switch away while it runs. Each disk is then re-verified (§5), cleanly unmounted
(so the partition rewrite cannot fire a spurious “Disk Not Ejected Properly” notification), then
eraseDisk'd, with one retry.find … | LC_ALL=C sort -z) and creates every folder and file with its
final name, in strict byte-sorted path order — no temp files, no renames. Because the target
volume is freshly formatted, each FAT directory entry is created in exactly that order, and
minimal player firmware that reads files in directory-entry order (rather than sorting them itself)
plays the content in the intended sequence. This is why the content folders and files are numbered
(001…, 002…): the numbering is the play order, and the ordered writer
preserves it onto the device.
rsync? Earlier versions used rsync -rt, trusting its
sorted file list — and a real player exposed the flaw: Apple's openrsync writes each file under a
.name.XXXXXX temporary name and renames it into place, and on FAT every rename re-allocates
the directory entry first-fit into slots freed by earlier temp entries, scrambling the final
entry order (name-length dependent, so small tests can pass by luck). The fix was reproduced from the
affected source folder and verified by parsing the raw FAT directory tables: the ordered writer yields
exact name-sorted entry order in every directory. Any substitute copy tool must create files with
final names in sorted order — an rsync-style temp/rename strategy will corrupt play order.
Some players are firmware-updated by copying a single firmware file (typically a
.ufw file, though a maker may ship any extension) onto the root of an otherwise-empty
device, which self-installs on the next power-on. The --firmware flag reuses the entire
engine above — whole-disk erase, volume label, ordered copy, junk scrub, eject, parallel across every
selected device — but the manifest is a single entry (the chosen file, written to
the volume root), so no folder walk, content check, simple-numbers renaming, or player profile applies.
bash load_content.sh --firmware (from the DMG,
bash /Volumes/<image>/.loader/load_content.sh --firmware). --update-firmware
and --fw are accepted aliases; --help lists all options.choose file
dialog showing all files (so a non-.ufw file is selectable); text/SSH mode reads a typed
path; a path argument is accepted (and is how run-again reuses the same firmware file). The file's
containing directory becomes the source disk protected from erasure, exactly as a content folder would.These are the checks that matter for “is it safe to run/re-publish.” Most exist because an earlier version lacked them and adversarial review found a concrete failure.
| Guard | Mechanism | Why |
|---|---|---|
| Never erase the source | Resolve the content folder's physical disk(s) via df → Part of Whole → APFS Physical Store, and exclude them from the target list. |
df reports an APFS synthesized node; without the walk, a source kept on an external APFS SSD could be selected and erased. |
| Skip write-protected media | Skip any disk whose diskutil info reports Media Read-Only: Yes. |
Hardware-locked cards (e.g. MegaVoice CSD lock) can't be written; skipping avoids confusing mid-run failures. |
| External physical only | Targets come solely from diskutil list external physical, plus internal
removable media on a card-reader protocol (the built-in SD slot) — never an internal
SSD/HDD or an APFS synthesized container. |
Internal disks are never enumerated as candidates. |
| Two-step human confirmation | A disk picker (deselect to keep) plus a distinct “ERASE / KEEP” summary dialog defaulting to Back. | Shows exactly what will be wiped, by size and volume name, before any destruction; the plain-click-replaces-selection trap is defused by the second dialog. |
| Pre-erase identity re-check | Immediately before each eraseDisk, re-verify the disk's exact byte size equals what was shown and it is still external+physical; else skip. |
macOS reuses diskN numbers; a device unplugged/replugged while the dialog was open could otherwise map the identifier to a different disk (TOCTOU). |
| Post-erase volume verify | Copy only to a disk whose freshly mounted volume has the chosen label and whose mount resolves to /dev/diskNs1. |
If an erase silently failed, an old/foreign partition could otherwise be copied onto and reported OK. |
Copy-time mount re-verify (ok_mount) |
Before and after the copy, confirm df <mount> is still /dev/diskNs1; during the copy the progress monitor re-checks the same identity every poll and, after two consecutive misses (~4 s), kills that transfer and removes any stray boot-disk folder the yank left behind. |
If a device vanishes, macOS can leave /Volumes/<name> as a plain folder on the boot disk; writing there would copy the payload onto the internal drive. |
| Blink write guard | The LED-blink loop re-checks df == /dev/diskNs1 before every write, and only blinks volumes named as the current or REDO label. |
Devices are unplugged while the end-of-run dialog is up (the operator sorts them by light), and any hard-yank can leave a ghost mountpoint; without this guard the blink writes would land on the boot disk (same class as above). |
| Consent-first side effect | The one host setting it toggles (DSDontWriteUSBStores) is changed only after the erase
is confirmed, and restored on exit (§9). |
A user who cancels leaves their Mac untouched. |
| Stall timeout | A copy with zero write progress for STALL_LIMIT (300 s) is killed and marked REDO. |
A dying device can't wedge the whole batch. |
| Interrupt handling | trap on INT/TERM/HUP stops blink loops, kills jobs, and lists incomplete devices; an EXIT trap stops blinkers, removes the temp dir, and restores the host setting. |
Ctrl-C leaves a clear record of which devices must not be distributed; HUP covers a closed Terminal window. |
| Blinkers cannot outlive the script | Each blink loop re-checks every iteration that the flag file exists and the main script's PID is still alive (kill -0 $$), exiting on its own otherwise. |
Even a force-quit / kill -9 (which fires no traps) cannot leave orphaned loops writing to devices after the script is gone. |
| Label sanitization | Alphanumeric only, uppercased, ≤11 chars. | FAT stores labels uppercase; punctuation can be transformed by diskutil, which would break the post-erase name check. |
Erase and copy both fan out one background subshell per device and wait. Each subshell
writes a single status file into a private mktemp -d directory; the main process polls
those files to drive the progress bar and the final grouping — there is no shared mutable state
between workers. The LED-blink loops are background jobs governed by a flag file and stopped with
kill/pkill (never an unbounded wait, so a device stuck in I/O
can't hang the script); each loop also re-checks every iteration that the main script's PID is still
alive, so no blinker can survive the script's exit — however it exits. ANSI colour is emitted only to
a TTY and is kept out of the status files so parsing stays clean.
dd or Balena Etcher) writes the entire image — including empty space — to each
device, and typically reads it all back to validate; a 2 GB image can mean up to ~4 GB
of I/O per device. This tool instead does a plain ordered file copy of just the real content
(only your actual content — ≈1.6 GB in the original deployment), with no image and no
read-back verification pass. Three things compound the win:
.metadata_never_index marker
written the moment each fresh volume mounts stops mds/mdworker from ever indexing it, which
would otherwise contend for the device's limited I/O — a real drag when many cheap USB devices are
written simultaneously (§7).macOS forces some metadata onto any FAT volume it mounts. The script's posture, verified against the OS:
.DS_Store — Finder's writing of it to USB volumes is suppressed for the duration of a
run (machine-wide default, restored on exit — see §9) so none can land ahead of the content in FAT
directory order; it is also excluded from the copy and scrubbed off each device as backstops.._* AppleDouble — cannot be prevented on current macOS: they are synthesized
on FAT for any file carrying the unclearable com.apple.provenance xattr. They are therefore
scrubbed after the copy (dot_clean + find -delete), not prevented..Spotlight-V100 — prevented: a .metadata_never_index marker is written to
the volume root at mount, and Spotlight then never creates its index folder at all (verified on
current macOS). The marker is deliberately left on the finished device so a verification re-plug —
or any future Mac — cannot re-junk the volume. On an older macOS that ignores the marker the folder
may still appear; it is SIP-protected, tiny, harmless, and not treated as junk..fseventsd/no_log — the sanctioned marker that stops event logging; tiny, unavoidable, left in place.._* sidecars cannot affect play order.
Creation is unpreventable without root: the sidecar is materialized by the kernel's AppleDouble shim
because every new file is stamped with the com.apple.provenance xattr, which
xattr -c cannot clear (verified empirically). But deletion is truly clean at the FAT
level: parsing the raw directory table of a freshly loaded volume shows the content entries live and in
exact sorted order, with the scrubbed sidecars reduced to 0xE5-marked free slots
between them. A free slot is not a file — the FAT specification requires every reader, minimal player
firmware included, to skip it (firmware that did not would fail on any disk that ever had a file
deleted, including Windows-prepared ones). Verified against real hardware: a device loaded and scrubbed
this way plays in correct order on a KULUMI Mini.
Net on each finished device: only .metadata_never_index and .fseventsd/no_log —
two tiny hidden files, both purposeful (they keep Spotlight and fseventsd from writing anything bigger).
The script does not set a read-only flag on the files (chflags uchg would
re-create removable-but-annoying ._* sidecars, and a clean volume was judged more valuable;
most players/Android ignore the flag anyway).
Every device ends in exactly one bucket:
OK; the on-screen group is GOOD.)REDO, left connected, and have their LED blinked (by forced writes) so the operator can find them.The end-of-run dialog offers Run again (or Done) for both success and failure; on
“Run again” the script cleans up (stops blink loops, removes its temp dir) and execs a
fresh copy of itself for the next batch. Because successfully loaded devices are ejected and detach,
a re-run naturally shows only the still-connected failures.
The script makes no network connections and contains no telemetry, analytics,
or update checks. It reads only the content folder and the attached disks, and writes only to the
selected external devices. It reads the Mac's computer name (scutil --get ComputerName)
solely to reference it in on-screen guidance.
It does not modify the source folder, and the one persistent host setting it touches is captured and restored, so nothing is left changed:
DSDontWriteUSBStores (machine-wide Finder default) — set to true for the
duration of a run so Finder cannot write a .DS_Store onto a device ahead of the content
(which would take an early FAT directory slot). The script records the pre-run value first and
restores it on exit via the cleanup EXIT trap — writing back true/false,
or deleting the key if it was originally absent. The original is captured once and carried across the
run-again re-exec, so restoration happens only when the whole session ends (Done, a dead-end, or Ctrl-C),
i.e. after every device has been written and ejected — never between batches. Belt-and-suspenders on top
of this, junk is also kept off devices by the copy loop's exclude filters and a per-device scrub (§7)..metadata_never_index
marker file on the device itself (no mdutil, no host or global preference of any kind); it is
erased with the device on the next run..DS_Store/._*
out of the copy, so there is no need to strip the source's own extended attributes or delete from it..fseventsd (OS-mandated; no_log keeps it to one empty file). A
.Spotlight-V100 is prevented on current macOS via .metadata_never_index; if an older
macOS creates one anyway it cannot be removed without root (SIP) and is left in place.diskutil and Apple's osascript.rsync or any temp-file-and-rename copier — on FAT that scrambles directory-entry order (§4 callout).The script is a single self-contained file with no obfuscation; every destructive command is
diskutil eraseDisk and every write target is validated against /dev/diskNs1
immediately before use. To audit quickly: read the guards in §5 against the code, and grep for the
three writers that touch disks — eraseDisk, the ordered copy loop's cp, and the blink
dd — confirming each is preceded by the identity/mount check described above. The tool was
hardened across several rounds of adversarial review; the current guards are the result.
Audio Player Loader is licensed under the GNU Affero General Public License, version 3.0
(AGPL-3.0).
Copyright © 2026 Seth Johnston.
The full license text is included as LICENSE.txt and is the authoritative terms. The
summary below is plain-language guidance, not legal advice.
You are free to use, study, modify, and redistribute this script — including on your own website, for your own devices and content. There is no fee and no need to ask permission.
Rebrand it freely. The APP_TITLE variable at the top of the script sets
the name shown in every dialog, notification, and the Terminal title. Device manufacturers and others
are explicitly welcome to change it to their own product name and ship it for their own players — the
author encourages this. (Under AGPL-3.0 your rebranded version must still stay open source under the
same license and keep the original copyright notice alongside your own.)
You may host it, adapt it for your own player devices and audio content, and share it, provided you
(1) keep it under AGPL-3.0, (2) include LICENSE.txt and this copyright notice, and (3) offer
your recipients (or your network users, if you run a modified version as a service) the corresponding
source of whatever version you ship. If those terms don't fit your use, contact the copyright holder to
ask about a separate licensing arrangement.