This is a collection of scripts to quickly set up a Bash environment. It has a bias towards game development. Features (non-exhaustive) include:
- Directory bookmarks.
- Templates for new projects.
- Shortcuts/piping into text editors.
- Various command completions.
- Application launchers/helpers.
- Portable Bash environment setup for macOS, Cygwin/Windows, and UNIX-like systems.
- Directory bookmarks.
- Project and script templates.
- Git, CMake, Unity, Android/ADB, Blender, Markdown, and video helpers.
- Platform-specific aliases and completions.
- Hierarchical
.bcconfigconfiguration. bcui, a local browser UI for metadata-backed commands.- Metadata-backed Bash completion for grouped commands and
video.
Implementation and future architecture notes live in design.md. This README is the user-facing reference for available features and commands.
These are loaded into every interactive shell:
| Command | Purpose |
|---|---|
cls |
Clear the terminal. |
h |
Show shell history. |
.., ..., .... |
Move up one, two, or three directories. |
gg, ggf, ggs |
Git log graph aliases. |
bs <name> |
Save the current directory as a bookmark. |
g <name> |
Change directory to a saved bookmark. |
bp <name> |
Print a bookmark path. |
bd <name> |
Delete a bookmark. |
bl |
List bookmarks. |
tmpfile |
Generate a temporary filename. |
b2h <bytes> |
Convert a byte count to a human-readable size. |
duh [path] |
Show sorted disk usage and total size. |
tree |
Fallback directory tree printer if the real tree command is absent. |
command_exists <name> |
Test whether a command is available. |
colecho |
Print coloured terminal text. |
bc_cfg_get <section> <key> [fallback] |
Read a value from the effective .bcconfig. |
clr_*, clr_dump |
Terminal colour helpers. |
These commands live in the bash_common root and are available after .profile
adds BC_INSTALL_DIR to PATH:
| Command | Purpose |
|---|---|
bashcommon |
Self-management: init, update, config, ui, doctor, list. |
project |
Project setup and build helpers. |
files |
File operation helpers. |
android |
Android/ADB helpers for Unity and game development. |
blender |
Blender launch and Python helpers. |
docs |
Documentation helpers (cheat sheets, Markdown). |
safari |
Safari/macOS browser data helpers. |
video |
Unified ffmpeg-backed video command with subcommands. |
bcinit |
Check/install dependencies, shell setup, and user config. |
bcconfig |
Show, query, and initialise .bcconfig settings. |
bcui |
Start the local browser UI for metadata-backed commands. |
bcdoctor |
Validate metadata-backed command discovery. |
bcup |
Update bash_common and, optionally, bundled completions. |
All video operations are unified under the video command (Python3, backed by ffmpeg):
video info FILE— print codec, resolution, duration, and bitratevideo convert [-f FORMAT] [-o OUTPUT] FILE— transcode to MP4 (H.264/AAC), WebM, MKV, or MOVvideo concat [-o OUTPUT] FILE...— join videos of the same format and resolutionvideo clamp [-s START] [-e END] [-o OUTPUT] FILE— cut to a time range;-sand-eare optional (omit-sto start from the beginning, omit-eto go to the end)video thumb [-t TIME] [-o OUTPUT] FILE— extract a single frame as a PNG imagevideo catalog [-o OUTPUT] DIR— scan a directory tree recursively and write a self-contained HTML report (name, size, duration, format, codec, resolution, fps, audio, bitrate)video normalise [-n] [-f] DIR— batch-normalise a directory tree to H.264/AAC MP4 at 720p; deinterlaces CRT/interlaced footage, upscales low-res content with lanczos, moves originals to a configurable backup directory.-ndry-run (writes a green/red HTML assessment report without converting),-fforce re-process
Run video <subcommand> -h for per-subcommand help.
Dependencies: ffmpeg and ffprobe must be on PATH. Run bcinit to install.
All Android/ADB operations are unified under the android command (Python3, backed by adb):
android install [APK] [--package PKG]— install an APK; force-stopsPKGfirst if knownandroid uninstall [PACKAGE]— uninstall a packageandroid run [PACKAGE] [--activity ACTION] [--component COMP]— launch the main activityandroid log [-o FILE] [-F FILTER] [-f] [--append]— capture logcat output to a file;-falso streams to terminalandroid list [--all]— list third-party (or all) installed packagesandroid dump [PACKAGE]— dump package info from the deviceandroid activity [PACKAGE]— show the launcher activity for an installed packageandroid devices— list connected devices and emulatorsandroid adb ARGS...— passthrough to the resolved adb binaryandroid config [--json]— print effective[android]config and the resolved adb path
Run android <subcommand> -h for per-subcommand help.
Configuration lives under [android] in .bcconfig. Available keys: adb,
unity_path, apk, package, activity, log_file, logopts. ADB is
located in this order: [android] adb → Unity's bundled adb under
[android] unity_path → adb on PATH.
Legacy ~/.uadb and ./.uadb files (the old KEY=VALUE format) are still
read for backwards compatibility; values from .bcconfig override them.
Dependencies: adb.
bcui starts a local Flask web server for interacting with bash_common commands
in a browser:
bcuiBy default it binds to 127.0.0.1:8765. The UI discovers commands that expose
machine-readable metadata, shows their subcommands and options, runs them as
structured argument lists, runs jobs in the background, displays stdout, stderr,
exit status, and known artifacts, and lets running jobs be cancelled.
Useful options:
bcui --host 127.0.0.1
bcui --port 8765
bcui --cwd /path/to/project
bcui --no-browser
bcui --host 0.0.0.0 --allow-lanBy default bcui refuses non-localhost binds because it can execute local
commands. Use --allow-lan only on a trusted network.
Dependency: Flask, installed by bcinit into bash_common's local .venv.
All grouped commands are first-class Python commands with full subcommand
metadata, proper argparse, and .bcconfig integration.
| Command | Subcommands |
|---|---|
bashcommon |
init, update, config, ui, doctor, list |
project |
git-init, unity-init, shell-script, cmake, cmake-dir |
files |
rename, format-cpp |
android |
install, uninstall, run, log, list, dump, activity, devices, adb, config |
blender |
launch, python, config |
docs |
cheat, markdown |
safari |
cookies |
bash_common loads metadata-backed completion for commands that expose
--bc-metadata. Completion covers subcommands, declared options, option choices,
and path-like arguments. Metadata is cached by command file modification time,
so completion stays responsive as more commands are added.
Examples:
video <TAB>
video convert --<TAB>
video convert --format <TAB>
project <TAB>
android <TAB>Use bashcommon doctor to validate metadata-backed command discovery:
bashcommon doctor
bashcommon doctor --jsonThis reports commands that publish invalid metadata, fail during metadata discovery, or time out.
Use bashcommon list to enumerate metadata-backed commands. The output is
sourced directly from each command's --bc-metadata, so it stays in sync as
commands evolve:
bashcommon list # human-readable summary
bashcommon list --with-subcommands # include each command's subcommands
bashcommon list --markdown # Markdown table for the README
bashcommon list --json # full metadata as JSONmacOS/Darwin loads darwin/_init.sh and adds darwin to PATH:
| Command | Purpose |
|---|---|
ls, ll, la |
macOS listing aliases. |
ql <file> |
Preview a file with Finder Quick Look. |
| `dtop [0 | 1]` |
ddd [-f] |
Delete Xcode DerivedData. |
love ... |
Launch Love2D. |
kom ... |
Launch Komodo Edit. |
diffmerge ... |
Launch SourceGear DiffMerge. |
rmate ... |
Remote TextMate helper. |
Cygwin/Windows loads cygwin/_init.sh and adds cygwin to PATH:
| Command | Purpose |
|---|---|
ls, ll, la |
GNU-colour listing aliases. |
open ... |
Open paths/URLs with cygstart. |
apt-cyg ... |
Cygwin package manager helper. |
UNIX/Linux/BSD/WSL loads unix/_init.sh and adds unix to PATH:
| Command | Purpose |
|---|---|
ls, ll, la |
GNU-colour listing aliases. |
bash_common uses .bcconfig files — INI-format files that can live in any
directory, working like .gitignore: settings in a directory apply to that
directory and all its children, with closer-to-pwd files overriding parent
ones. The global defaults live at ~/.bcconfig, created by bcinit.
.bcconfig is a standard INI file. Sections are named by command, with
sub-sections for subcommands separated by a dot:
[bash_common]
editor = mate
[video]
default_format = mp4
[video.convert]
video_codec = libx264
video_preset = medium
video_crf = 23
audio_codec = aac
audio_bitrate = 128k
[video.thumb]
time = 00:00:05
[video.normalise]
target_width = 1280
target_height = 720
original_dir = /tmp/video-originals
deinterlace = autoTo use different encoding settings for a specific project, place a .bcconfig
file in the project directory:
# ~/projects/myfilm/.bcconfig
[video.convert]
video_crf = 18
video_preset = slow
[video.normalise]
original_dir = ./originalsOnly the keys you specify are overridden; everything else falls back to the parent or global config.
bcconfig shows the effective merged settings for your current location,
with each setting annotated by which file it came from:
$ bcconfig video
Sources (base → leaf):
~/.bcconfig
~/projects/myfilm/.bcconfig
[video.convert]
video_codec = libx264 ~/.bcconfig
video_preset = slow ~/projects/myfilm/.bcconfig ← overridden
video_crf = 18 ~/projects/myfilm/.bcconfig ← overridden
audio_codec = aac ~/.bcconfig
audio_bitrate = 128k ~/.bcconfig
Usage:
bcconfig show all effective settings
bcconfig VIDEO filter to [VIDEO] and [VIDEO.*] sections
bcconfig --files list source files in load order
bcconfig --get video.convert.crf print a single value
bcconfig --get video.convert.crf --fallback 23
bcconfig --init create .bcconfig in cwd with all sections
bcconfig --init video.normalise create .bcconfig with only [video.normalise]
The bc_cfg_get bash function (available in every interactive shell) reads a
single config value — useful in scripts and custom functions:
editor=$(bc_cfg_get bash_common editor mate)
vcodec=$(bc_cfg_get video.convert video_codec libx264)Arguments: bc_cfg_get <section> <key> [fallback]
Clone to ~/.bash_common (the dot prefix keeps it hidden, consistent with other dot-files
in your home directory):
cd
git clone https://github.com/billyquith/bash_common.git .bash_commonAfter cloning, run bcinit to check and install all dependencies. System tools
such as ffmpeg, python3, mediainfo, and wget are installed through the platform
package manager; Python packages from requirements.txt are installed into
bash_common's local .venv.
~/.bash_common/bcinitPass -c to check without installing:
~/.bash_common/bcinit -cSource the bash_common .profile and .bashrc from your home ones. In ~/.bash_profile
source .bash_common/.profile and make sure your .bashrc is sourced:
[ -f ~/.bash_common/.profile ] && source ~/.bash_common/.profile # source bash_common profile
[ -f ~/.bashrc ] && source ~/.bashrc # ensure .bashrc sourcedIn your ~/.bashrc ensure that .bash_common/.bashrc is sourced:
[ -f ~/.bash_common/.bashrc ] && source ~/.bash_common/.bashrcbash_common is designed to work across three platform families, selected automatically
at startup by inspecting uname -s:
| Platform | BC_SYSTEM |
BC_OS |
Typical use |
|---|---|---|---|
| macOS | darwin |
macos |
Desktop development on Apple hardware |
| Windows | cygwin |
windows |
Cygwin terminal on Windows |
| Linux / UNIX | unix |
unix |
Linux distros, FreeBSD, WSL, CI/CD |
Platform-specific init scripts live in darwin/_init.sh, cygwin/_init.sh, and
unix/_init.sh. The unix label is intentionally broad — it is the catch-all for
anything that is not Darwin or Cygwin, including all Linux distributions (Ubuntu, Fedora,
Arch, etc.), BSDs, and WSL. There is no separate linux directory because there is no
behaviour that needs to be split at that level; distro differences (package managers,
etc.) are handled at install time by bcinit.
Each _init.sh sets platform-appropriate aliases and loads relevant completions. The
default EDITOR is also set per platform (TextMate on macOS, VS Code on Cygwin, vi
on UNIX).
EDITOR: default text/source editor to use.BC_INSTALL_DIR: where this lives, bin dir.BC_SYSTEM: platform identifier (darwin,cygwin, orunix).BC_OS: OS family (macos,windows, orunix).
macOS switched its default shell to zsh in Catalina (10.15), but this was driven by licensing: Bash 3.2 (2007) is the last version Apple could ship under GPLv2, and they were unwilling to bundle the GPLv3-licensed Bash 4+. The switch was a licensing decision, not a technical one.
Bash remains the right choice here because:
- Portability — Bash is the de facto standard on Linux, CI runners, Docker containers, and most cloud/server environments. Scripts written here work everywhere without modification.
- Maturity — Bash 5 is actively maintained and available via Homebrew on macOS
(
brew install bash). Over 40 years of shell scripting convention and tooling support it. - Ubiquity —
#!/usr/bin/env bashis universally understood. Most documentation, examples, and Stack Overflow answers are written for Bash.
macOS users should install a modern Bash and set it as their shell:
brew install bash
# Add /opt/homebrew/bin/bash (or /usr/local/bin/bash) to /etc/shells, then:
chsh -s /opt/homebrew/bin/bashThe system Bash at /bin/bash (3.2) is kept for compatibility with macOS scripts but
bash_common targets Bash 4+.
-
~/.bash_profileshould be super-simple and just load.profileand.bashrc(in that order). -
~/.profilehas the stuff not specifically related to BASH, such as environment variables (PATH and friends). -
~/.bashrchas anything for interactive command line. Command prompt, EDITOR variable, bash aliases for my use -
Anything that should be available to graphical applications or to
sh(or BASH invoked as sh) must be in~/.profile. -
~/.bashrcmust not output anything. -
Anything that should be available only to login shells should go in
~/.profile -
Ensure that
~/.bash_logindoes not exist.
- Textmate: https://github.com/Mr0grog/editorconfig-textmate
- Xcode: https://github.com/MarcoSero/EditorConfig-Xcode
git clone --recurse-submodules https://github.com/MarcoSero/EditorConfig-Xcode.git cd EditorConfig-Xcode open EditorConfig.xcodeproj