如何在 Claude chat、Colab 等沙盒中透過 julialang 安裝 Julia(apt、sudo 和 juliaup 不可用時)
How to install Julia inside Claude chat, Colab, and other sandboxes (when apt, sudo, and juliaup don't exist)
Mohammad Raziei 的 Python 套件 julialang 讓用戶只靠 pip,便可在 Claude chat、Google Colab 等沙盒中安裝及管理 Julia 版本。
The wall I hit
If you've ever tried to run Julia in a sandboxed environment, you know the sequence:
- You try
apt install julia— permission denied. - You try
curl -fsSL https://install.julialang.org | sh— the domain is blocked, or the installer fails silently. - You try
juliaup— it wants to modify your shell config, and the sandbox doesn't allow it. - You try downloading a tarball manually — you can't extract it where you want, or the path isn't writable.
And then you look around and realize: the only tool you have that actually works is pip.
That was my exact situation. I was working inside Claude chat's sandbox — the environment where the assistant can run code on your behalf — and I wanted to test a Julia snippet. Julia simply wasn't installable. Not with the tools the Julia community officially provides.
So I wrote julialang: a pip package that installs, switches, and removes Julia versions using nothing but pip.
pip install julialang && julialang install && julia
Three commands. No installer, no apt, no juliaup, no julialang.org.
Why this works where other tools fail
The key insight is simple: the Julia language itself doesn't need to be inside the pip wheel. The wheel only needs to be a small, portable installer that knows how to fetch the real thing.
This is the same pattern ziglang uses for Zig, and it works beautifully for Julia too.
flowchart LR
A[julialang.org<br/>downloads pages] -->|crawl| B[tools/sync.py]
B -->|verify sha256 + md5| C[GitHub Releases]
C -->|julia-list.json| D[pip install julialang]
D --> E[julialang install]
E -->|download + verify| F[~/.julialang/versions/<version>/]
F --> G[julia / julialang run]What this buys you:
-
Tiny wheel.
pip install julialangdownloads a few KB of pure Python. The same wheel works on every platform (py3-none-any). -
No system-level permissions. Everything installs into
~/.julialang, which is writable in almost every sandbox. - No dependency on julialang.org. The binaries are mirrored on GitHub, which is reachable in more places than the Julia website.
- Multiple versions coexist. You can have Julia 1.10 and 1.12 installed at the same time and switch between them.
Step-by-step: Julia in Claude chat
This is the exact scenario I built it for. In a Claude chat, the assistant can run shell commands and Python, but you can't install Julia with the usual methods. Here's how it goes:
Step 1 — install the package:
pip install julialang
Step 2 — install Julia itself:
julialang install
This downloads the latest stable Julia, verifies its sha256 and md5, and unpacks it into ~/.julialang/versions/<version>/.
Step 3 — run it:
julia -e 'println("hello from Julia ", VERSION)'
If julia isn't on your PATH — which is common in sandboxes that don't pick up ~/.local/bin — use the shim instead:
julialang run -e 'println(VERSION)'
python -m julialang run script.jl
Both of these route to the same Julia binary. The shim exists precisely because sandbox environments are unpredictable about what ends up on PATH.
The same recipe works in Google Colab, GitHub Actions runners, locked-down CI containers, and any environment where pip is your only escape hatch.
The commands you'll actually use
flowchart LR
subgraph Install
I1[julialang install] --> I2[latest, becomes default]
I3["julialang install '>=1.10,<1.13'"] --> I4[newest match]
I5[julialang install 1.10 1.12] --> I6[multiple at once]
end
subgraph Run
R1[julia script.jl] --> R2[shim → selected version]
R3[julialang run -e '...'] --> R2
R4[python -m julialang run ...] --> R2
end
subgraph Manage
M1[julialang use 1.10] --> M2[switch default]
M3[julialang list] --> M4[see what's installed]
M5[julialang uninstall 1.12] --> M6[remove one]
M7[julialang self-uninstall] --> M8[purge + pip uninstall]
endA fuller walkthrough:
# Install and inspect
julialang install # latest Julia, becomes default
julialang install 1.12 # the newest 1.12.x
julialang install 1.10.5 # exactly this version
julialang install ">=1.10,<1.13" # pip-style version specs
julialang install 1.10 1.12 # several at once
# See what you have
julialang # status: installed, default, latest
julialang list --installed # only what's on your machine
julialang list --all # everything the mirror offers
julialang latest # newest version available
julialang which # path of the executable `julia` runs
# Run
julia # REPL
julia script.jl # run a script
julialang run -e 'println(VERSION)' # when `julia` isn't on PATH
python -m julialang run script.jl # when even the shim isn't on PATH
JULIALANG_VERSION=1.10 julia -e 'print(VERSION)' # one command, another version
# Switch between versions
julialang use 1.10
julialang use latest
# Upgrade and downgrade (these REPLACE the default)
julialang upgrade # install latest, make it default, remove old default
julialang upgrade 1.12 # ... or the newest 1.12.x
julialang downgrade 1.10 # towards an older version
# Remove
julialang uninstall 1.12.2 # one version
julialang uninstall 1.10 1.11 # several
julialang uninstall "<1.12" --yes # a spec that matches many versions
julialang purge # remove every Julia version + data
julialang self-uninstall # purge, then `pip uninstall julialang`
How version selection works
When you invoke julia or julialang run, the choice of which Julia to run is fully deterministic:
flowchart TD
A[invoke julia] --> B{JULIALANG_VERSION set?}
B -->|yes| C[use that version<br/>must be installed]
B -->|no| D{default configured?}
D -->|yes| E[use default]
D -->|no| F{any version installed?}
F -->|yes| G[use newest installed]
F -->|no| H[error: run julialang install<br/>or set JULIALANG_AUTO_INSTALL=1]Two things are worth calling out:
-
The shim never touches the network. Running
juliashould never silently download something. If nothing is installed, it tells you to runjulialang install. -
JULIALANG_AUTO_INSTALL=1is the opt-in escape hatch for people who wantjuliato fetch the latest version on first use. It's off by default on purpose.
Version specs: pip semantics, npm-style partials
If you've used pip version specifiers, these will feel familiar:
| Spec | Meaning |
|---|---|
latest (or nothing) |
the newest version |
1, 1.12, 1.12.*, ==1.12
|
the newest 1.x / 1.12.x |
1.12.4, ==1.12.4
|
exactly that version |
!=1.12.4 |
anything but 1.12.4 |
>=1.10, <1.13 |
comparison, as in pip |
<=1.12, >1.12
|
with a partial version the whole line counts: <=1.12 includes 1.12.x |
~=1.12.2 |
compatible release: >=1.12.2,<1.13
|
>=1.10,<1.13 |
comma-joined: every part must hold, the newest match wins |
Quote specs that contain < or > so the shell doesn't treat them as redirection.
Why not juliaup?
juliaup is excellent. It's the official tool, it's well-maintained, and if you can run it, you probably should. But juliaup assumes a few things that sandboxes don't always give you:
flowchart LR
subgraph juliaup["juliaup"]
J1[needs shell config] --> J2[writes to ~/.juliaup]
J2 --> J3[fetches from julialang.org]
end
subgraph julialang["julialang (pip)"]
P1[needs only pip] --> P2[writes to ~/.julialang]
P2 --> P3[fetches from GitHub mirror]
endjulialang makes exactly one assumption: if your environment can install a Python package, it can install Julia.
Under the hood: two workflows that never talk
One design decision I'm happy with is that the mirror sync and the package release are completely decoupled.
flowchart TB
subgraph Sync["sync.yml — mirror only"]
S1[push / weekly cron / manual] --> S2[crawl + download Julia]
S2 --> S3[upload to GitHub Releases]
S3 --> S4[update julia-list.json asset]
end
subgraph Wheel["wheel.yml — package only"]
W1[push to master] --> W2[ruff + pytest]
W2 --> W3[build wheel/sdist]
W3 --> W4[smoke test on 5 OSes]
W4 --> W5[beta prerelease]
W6[tag vX.Y.Z] --> W2
W6 --> W7[GitHub release + PyPI]
end
S4 -.->|read at install time| W4The dashed line is the only connection: the wheel's smoke test actually installs Julia from the mirror on five operating systems, so every release doubles as a health check of the mirror. But neither workflow triggers the other — a broken mirror doesn't block a release, and a release doesn't depend on the sync job finishing.
julia-list.json isn't in git — it's a release asset, regenerated after every mirrored version.
Integrity, honestly
flowchart LR
A[GitHub mirror] -->|archives| B[julialang install]
A -->|julia-list.json<br/>sha256 + md5| B
B --> C{hashes match?}
C -->|yes| D[install]
C -->|no| E[abort]
F[⚠️ same origin] -.-> AThat last note matters. The hashes and the archives come from the same repository, so this protects against corrupted downloads — not against someone taking over the mirror. I'm calling that out openly because it's the honest trade-off of this design.
In a high-security environment, juliaup from the official source is the safer choice. For everyone else — the person in a Colab notebook, a CI runner, a sandbox — the trade-off is worth it.
Environment variables
| Variable | Effect |
|---|---|
JULIALANG_HOME |
where versions, config.json, and the cache live (default ~/.julialang) |
JULIALANG_VERSION |
spec of an installed version that julia should run |
JULIALANG_AUTO_INSTALL=1 |
let julia install the latest version on first use |
JULIALANG_REPO |
GitHub repository to read the mirror from |
JULIALANG_LIST_URL |
full URL of julia-list.json, overriding JULIALANG_REPO (useful for your own mirror or tests) |
The state layout is simple: ~/.julialang/versions/<version>/ holds each Julia, and ~/.julialang/config.json records the default and installed versions. It re-syncs with the folders on every command, so you can even delete a version folder by hand.
Try it
pip install julialang
julialang install
julia -e 'println("it works: ", VERSION)'
If you've ever been stuck in an environment that only speaks pip, I'd love to hear whether this solves your problem — and what's still missing. Issues and PRs are very welcome.
Julia is a wonderful language. Getting to it shouldn't require admin rights.
來源:DEV Community · dev.to