Question
I installed rbenv by following the GitHub instructions. I am testing on both macOS and an Ubuntu 12.04 virtual machine, and I see the same behavior in each environment.
When I try to switch Ruby versions, rbenv appears to think the global version is set correctly, but the terminal still uses the system Ruby:
rbenv versions
* 1.9.3-p0 (set by /Users/user/.rbenv/version)
1.9.3-p125
rbenv global
# output
1.9.3-p0
rbenv rehash
ruby -v
# output
ruby 1.8.7 (2011-12-28 patchlevel 357) [universal-darwin11.0]
which ruby
# output
/usr/bin/ruby
rbenv local
# output
rbenv: no local version configured for this directory
Why is rbenv not actually switching the Ruby version, even though it reports the global version as changed?
Short Answer
By the end of this page, you will understand how rbenv selects a Ruby version, why which ruby may still point to /usr/bin/ruby, and how shell configuration and PATH determine whether rbenv works correctly. You will also learn how to diagnose and fix common rbenv setup problems on macOS and Linux.
Concept
rbenv does not replace the system Ruby directly. Instead, it works by placing shims at the front of your shell's PATH.
A shim is a small executable that stands in front of the real command. When you run a command like ruby, gem, or bundle, the shim asks rbenv which Ruby version should be active, then forwards the command to the correct Ruby installation.
If your shell is still finding /usr/bin/ruby, that means the rbenv shims are not being used first in PATH. In that case:
rbenv globalmay still show the version you selectedrbenv versionsmay still list installed Rubies- but
ruby -vwill keep showing the system Ruby
This is why rbenv can look correctly configured at first glance while not actually affecting the Ruby that runs.
The key idea is:
rbenvstores version settings- shell
PATHdecides whether those settings are used
Mental Model
Think of rbenv as a receptionist in front of several Ruby installations.
When you type ruby, your shell looks for the first ruby it can find.
- If it reaches
/usr/bin/rubyfirst, you get the system Ruby. - If it reaches the
rbenvshim first, the receptionist checks your configured version and sends you to the correct Ruby.
So the problem is usually not that rbenv forgot your chosen version. The problem is that the shell never asked rbenv in the first place.
Syntax and Examples
The most important rbenv commands are:
rbenv versions
rbenv global 3.2.2
rbenv local 3.2.2
rbenv shell 3.2.2
rbenv rehash
rbenv which ruby
A typical shell setup looks like this:
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
On newer setups, rbenv init usually adds the shims path for you. After configuration, check:
which ruby
ruby -v
rbenv which ruby
Expected result:
which ruby
# something like:
# /Users/yourname/.rbenv/shims/ruby
If you still get:
/usr/bin/ruby
then your shell is not using rbenv shims.
Example diagnosis
Step by Step Execution
Consider this example:
rbenv global 1.9.3-p125
ruby -v
which ruby
Here is what happens step by step:
-
rbenv global 1.9.3-p125rbenvwrites the selected version into~/.rbenv/version.- This does not automatically force the shell to use that Ruby.
-
ruby -v- Your shell searches the directories in
PATHfrom left to right. - If
/usr/bincomes before~/.rbenv/shims, the shell runs/usr/bin/ruby. - You see the system Ruby version instead of the version managed by
rbenv.
- Your shell searches the directories in
-
which ruby- This shows the exact executable your shell found.
- If it prints
/usr/bin/ruby,rbenvshims are not active.
-
If is configured correctly:
Real World Use Cases
This concept appears often in real development work:
-
Working on old and new Ruby apps
- One project may need Ruby 2.7, another Ruby 3.2.
rbenvlets each project use the correct version.
-
Avoiding system Ruby changes
- macOS ships with a system Ruby that other tools may rely on.
- Version managers let you install your own Ruby safely.
-
Consistent team environments
- Teams can commit a
.ruby-versionfile so everyone uses the same Ruby.
- Teams can commit a
-
CI and deployment setup
- Build servers often use version managers or similar PATH-based tools.
- Understanding shims helps when scripts work locally but fail in CI.
-
Debugging command conflicts
- Many tools such as
pyenv,nodenv, andasdfuse the same idea. - Learning this once helps across multiple ecosystems.
- Many tools such as
Real Codebase Usage
In real projects, developers usually combine rbenv with a few practical patterns:
Project-specific Ruby with .ruby-version
A codebase often includes:
.ruby-version
Example content:
3.2.2
This lets rbenv automatically switch when you enter the project directory.
Guard checks in setup scripts
Teams often add checks like:
ruby -v
bundle -v
which ruby
This catches environment mistakes early.
Early validation in documentation
Many projects include setup instructions such as:
which ruby
# should be ~/.rbenv/shims/ruby
This is a fast sanity check before installing gems or running the app.
Rehash after installing executables
After installing gems that add commands, developers run:
rbenv rehash
This regenerates shims for executables like:
Common Mistakes
1. Setting the global version but not initializing rbenv
This is the exact issue behind many cases like this one.
Broken situation:
rbenv global 1.9.3-p125
ruby -v
# still shows system ruby
Why it happens:
- the version is saved
- but the shell is not using
rbenvshims
How to avoid it:
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
Then restart the shell.
2. Checking only rbenv global
Broken assumption:
rbenv global
# correct version shown
This does not prove that ruby is using that version.
Always also check:
which ruby
ruby -v
3. Forgetting that order matters
Comparisons
| Concept | What it does | Scope | Common use |
|---|---|---|---|
rbenv global | Sets the default Ruby version | User-wide fallback | Personal default Ruby |
rbenv local | Sets Ruby version for one directory | Project-specific | App-level Ruby version |
rbenv shell | Sets Ruby version for current shell only | Temporary session | Testing a version quickly |
rbenv rehash | Rebuilds executable shims | Tooling support | After installing gems |
which ruby | Shows what executable the shell will run |
Cheat Sheet
# Show installed Ruby versions
rbenv versions
# Set default Ruby for your user
rbenv global 3.2.2
# Set Ruby for current project
rbenv local 3.2.2
# Set Ruby only for this terminal session
rbenv shell 3.2.2
# Show active version according to rbenv
rbenv version
# Show the actual ruby command your shell runs
which ruby
# Show the ruby executable rbenv resolves to
rbenv which ruby
# Rebuild shims after installing gem executables
rbenv rehash
Required idea
rbenv only works if your shell uses its shims.
Typical shell setup
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
Healthy setup signs
which ruby
# ~/.rbenv/shims/ruby
ruby -v
# selected version
Red flag
which ruby
FAQ
Why does rbenv global change the version but ruby -v does not?
Because rbenv saved the version, but your shell is still running a different ruby executable, usually /usr/bin/ruby.
How do I know if rbenv is working correctly?
Run:
which ruby
ruby -v
If which ruby points to ~/.rbenv/shims/ruby, rbenv is active.
What does rbenv rehash do?
It regenerates shims for Ruby executables provided by installed gems. It does not fix PATH or shell initialization problems.
Why does which ruby show /usr/bin/ruby?
Because your PATH is finding the system Ruby before the rbenv shims directory.
Do I need both rbenv and ?
Mini Project
Description
Build a small shell-based diagnostic checklist for rbenv. The goal is to practice checking version settings, shell command resolution, and PATH behavior in a repeatable way. This mirrors what developers do when onboarding to a Ruby project or debugging a broken environment.
Goal
Create a command-line checklist that confirms whether rbenv is installed, initialized, and actually controlling the ruby command.
Requirements
- Print the current shell and current PATH.
- Show the outputs of
rbenv version,which ruby, andruby -v. - Detect whether
which rubypoints to anrbenvshim or to the system Ruby. - Print a helpful message explaining the likely issue.
- Work as a simple Bash script.
Keep learning
Related questions
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.