Setting up a new machine¶
A start-to-finish walkthrough: bare OS to a working shell, using
setup-system. That page is the reference — every flag,
every step, every option. This one is the narrative: what to run, what it does
to your machine, how to check it worked, and what to do when it didn't.
The short version¶
. <(curl -sSL https://just-buildit.github.io/get-jb.sh) # get jb + jbx
jbx setup-system --dry-run # read the plan
jbx setup-system # run it
exec bash -l # apply it
Four commands. The rest of this page is what each one does and why you might want to deviate.
Before you start¶
setup-system needs bash 3.2 or newer and curl. Everything else it either
installs or skips with a note.
It will:
- write two files under
~/.config/just-bashit/and append one line to each of~/.bashrcand~/.profile - create an ssh key only if
~/.sshhas none - set git defaults only where you have not already set a value
- install packages from a
jb.tomlin the current directory, if there is one
It will not: touch anything else in your ~/.bashrc, set user.name or
user.email, replace a key you already have, or overwrite a git setting you
chose. Re-running it is how you upgrade, not a mistake.
Read the plan first
--dry-run prints every command it would run and writes nothing at all.
On a machine you care about, run that before the real thing.
Step 1 — get jb and jbx¶
Sourced rather than piped to bash, so the PATH change applies to the shell
you are sitting in. If you pipe it instead, open a new shell afterwards.
jbx fetches a script, runs it, and discards it — nothing is installed for
setup-system itself. See just-runit.
Step 2 — look at the plan¶
just-bashit setup-system
dry run — nothing will be changed
==> deps — system packages
no jb.toml or jb-deps.toml in /home/you — nothing to install
==> shell — bash configuration
creating: /home/you/.config/just-bashit/bashrc.sh
would append to /home/you/.bashrc: if [ -r "$HOME/... "; fi
...
summary
deps: skipped (no deps file)
shell: ok (/home/you/.config/just-bashit)
The summary at the end is the thing to read: one line per step, saying what happened or why it didn't.
Step 3 — run it¶
Or a subset — the steps are independent and always run in dependency order, whatever order you name them in:
jbx setup-system -s shell,ssh # only these
jbx setup-system -x claude,tools # everything except these
The ssh step will prompt for a key passphrase if it generates one. Nothing
else is interactive.
Step 4 — apply it¶
Your current shell has already read its rc files; nothing you install changes
it retroactively. A login shell (-l) is what picks up ~/.profile, so use
that rather than plain exec bash the first time.
What changed on disk¶
~/.config/just-bashit/
bashrc.sh interactive settings — readline, history, aliases, prompt
profile.sh environment — PATH, EDITOR, ssh-agent
bashrc.d/ yours; sourced last, never overwritten
Plus one line in each of two files:
# ~/.bashrc
if [ -r "$HOME/.config/just-bashit/bashrc.sh" ]; then . "$HOME/.config/just-bashit/bashrc.sh"; fi
# ~/.profile (and ~/.bash_profile, if that file exists)
if [ -r "$HOME/.config/just-bashit/profile.sh" ]; then . "$HOME/.config/just-bashit/profile.sh"; fi
That is the whole footprint. Upgrading replaces the two files and keeps the
old copy as bashrc.sh.bak; uninstalling is deleting the two lines.
Which file gets read when¶
The split between the two files is the one design decision worth understanding, because it is what makes tooling outside your terminal work. Measured, not assumed:
| how the shell starts | reads profile.sh |
reads bashrc.sh |
|---|---|---|
console or ssh host login |
✅ | ❌ |
| terminal emulator tab | ✅ (via bashrc.sh) |
✅ |
bash -lc '…' |
✅ | ❌ |
bash -c '…' from a configured session |
inherited | ❌ |
ssh host CMD |
❌ | ❌ |
The stock ~/.bashrc on every distro opens with an interactive-only guard:
So exports placed there reach interactive terminals and nothing else.
~/.profile runs once per login session, and everything descended from
that session inherits its exports — scripts, language servers, agents, GUI
apps. That is why PATH and SSH_AUTH_SOCK live in profile.sh.
Because terminal emulators start non-login shells that never read
~/.profile, bashrc.sh sources profile.sh itself when no login shell has.
Both paths converge; neither duplicates the other.
ssh host CMD reads neither file
A remote command runs a non-login, non-interactive shell, which consults
no rc file at all — that is bash's behaviour, not something this
configuration changes. If ssh host 'git push' cannot find something,
use a login shell explicitly:
or put the variable in ~/.ssh/environment with PermitUserEnvironment.
Checking it worked¶
# arrows search history rather than walking it
bind -q history-search-backward
# → history-search-backward can be invoked via "\eOA", "\e[A".
# (some builds print the same sequences as "\M-OA", "\M-[A")
# one agent, holding your keys
echo "$SSH_AUTH_SOCK"
ssh-add -l
# the environment reaches non-terminal children
bash -lc 'bash -c "echo \$PATH"' | tr : '\n' | grep local/bin
Then the real test: press ↑ after typing a couple of characters. You should get your last command starting with those characters, not simply your last command.
Making it yours¶
Add things in ~/.config/just-bashit/bashrc.d/*.sh. Sourced last, so they
win, and untouched by upgrades.
Turn things off with a JB_* variable set in ~/.bashrc above the
source line. The full table is in the
reference; the ones people reach for:
| Variable | Effect |
|---|---|
JB_PROMPT_GIT=0 |
Prompt without the git branch — for very large repos |
JB_SAFE_ALIASES=0 |
No interactive rm/cp/mv guards |
JB_SSH_AUTOADD=0 |
Start an agent, but do not load keys into it |
JB_PROMPT=0 |
Keep your own PS1 |
Move the install with --prefix DIR if ~/.config is not where you want
it.
Per-environment notes¶
Works unmodified. XDG_RUNTIME_DIR is usually absent, so the agent
socket lands under $TMPDIR (or /tmp) in a 0700 directory instead —
same lifetime, same single agent per user.
The system /bin/bash is 3.2, from 2007. Everything here accounts for
that: bash 4 shell options are behind a version check and readline
settings that need a newer readline fail quietly.
One trap that is not ours: if ~/.bash_profile exists, bash reads it
for login shells and ignores ~/.profile entirely. setup-system
keeps both in step when both are present.
Skip what a container has no use for, and never wait on a prompt:
--yes means no prompts — which for the ssh step means a key with an
empty passphrase. Right for an ephemeral runner, wrong for a laptop.
Using it as your project's onboarding command¶
Declare the steps and the system packages in jb.toml, and a new contributor
runs one command:
[tools.setup-system]
source = "just-bashit:setup-system"
steps = ["deps", "tools"]
[dev.apt]
packages = ["build-essential", "cmake"]
[dev.pacman]
packages = ["base-devel", "cmake"]
They get the project's system packages and uv + pre-commit hooks, and not
your opinions about their prompt. -s on the command line always overrides
the steps key, so anyone who does want the shell config can ask for it.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Nothing changed | The shell you ran it in had already read its rc files | exec bash -l |
| ↑ still walks history | Something sourced after our line rebinds the arrows | bind -q history-search-backward shows the current binding; move the source line later in ~/.bashrc |
| Passphrase asked in every new terminal | The agent is not persisting | echo $SSH_AUTH_SOCK in two terminals — if it differs, something else is setting it; JB_SSH_AGENT=0 to stand down |
| Prompt is slow | git diff on a very large repo |
JB_PROMPT_GIT=0 |
[x1] instead of [✗1] |
Locale is not UTF-8 | Intentional — the mark degrades rather than producing mojibake |
ssh host CMD can't find a tool |
That shell reads no rc file | ssh host -t bash -lc '…' |
| Login is slower than it was | ssh-add is prompting, or a slow drop-in |
JB_SSH_AUTOADD=0 to test; then bisect bashrc.d/ |
Uninstalling¶
# 1. remove the two source lines
jbx just-bashit:file remove-line \
'if [ -r "$HOME/.config/just-bashit/bashrc.sh" ]; then . "$HOME/.config/just-bashit/bashrc.sh"; fi' \
~/.bashrc
# 2. and the files, if you want them gone
rm -rf ~/.config/just-bashit
Or open ~/.bashrc and ~/.profile and delete the lines by hand — there are
only two, and they are commented. Nothing else was modified, so there is
nothing else to undo.
See also¶
setup-system— the full flag and step reference- Templates — reading the two shell templates on their own
install-deps— thedepsstep, and thejb.tomlpackage formatjust-runit— howjbxfetches and runs a script