How to Update Perl in Linux (Safely): Package Managers, perlbrew, and Source Builds
Question
how to update perl in linux
Difficulty
Intermediate (beginner-friendly steps included, but choices affect system stability).
Tags
perl, linux, package-management, perlbrew, cpan, cpanminus, build-from-source, devops
Overview: What “updating Perl” really means
On Linux, “updating Perl” can mean different things depending on where your Perl comes from and how it’s used:
- System Perl: The Perl interpreter provided by your distribution (Debian/Ubuntu, RHEL/Fedora, Arch, Alpine, etc.). Many OS tools and packages may rely on it.
- User-managed Perl: A separate Perl you install for your own apps (often via
perlbreworplenv), without touching the system Perl. - Modules: CPAN modules (dependencies) are separate from the Perl interpreter version; you may need to update them too.
The safest default is: leave the system Perl alone and install a newer Perl for your applications using a version manager (usually perlbrew).
Step 0: Identify what you currently have
Before changing anything, confirm which Perl is being used and what version it is:
which perl
perl -v
perl -e 'print "Perl executable: $^X\nPerl version: $^V\n"'
Why this matters: You might have multiple Perls (for example, /usr/bin/perl and a user-installed one in $HOME/perl5), and the one first on $PATH is the one you actually run.
Option A (recommended for system stability): Update Perl via your Linux package manager
This updates Perl within the constraints of your distribution release. It’s the right choice if you want the vendor-supported Perl, security updates, and minimal surprises.
Debian/Ubuntu
sudo apt update
sudo apt install --only-upgrade perl
# or update everything (common on servers you manage as a unit)
sudo apt full-upgrade
Notes: On stable distributions, Perl may not jump to the newest major/minor line. You get the distro’s supported version plus security patches.
Fedora
sudo dnf upgrade perl
# or upgrade all packages
sudo dnf upgrade
RHEL/CentOS/Rocky/Alma
sudo dnf upgrade perl
# older systems may use yum
sudo yum update perl
Notes: Enterprise distributions often ship older Perl versions intentionally. If you need newer, use Option B (perlbrew) rather than forcing the OS Perl to change.
Arch Linux
sudo pacman -Syu perl
Alpine Linux
sudo apk update
sudo apk upgrade perl
openSUSE/SLES
sudo zypper refresh
sudo zypper update perl
Best practice for package-manager updates
- Do not “replace” /usr/bin/perl manually. Let the OS own it.
- After upgrading, re-check:
perl -vand run your app’s test suite. - If your project depends on a specific Perl line, pin it via a user-managed Perl (Option B), containers, or CI matrices.
Option B (best for apps): Install and update Perl using perlbrew (user-managed)
perlbrew installs Perls into your home directory and lets you switch versions per shell or per project. This is the most common way to get a newer Perl on a server without risking OS breakage.
Install perlbrew
curl -L https://install.perlbrew.pl | bash
# then add perlbrew init to your shell (bash/zsh). Example (zsh):
echo 'source "$HOME/perl5/perlbrew/etc/bashrc"' >> ~/.zshrc
# reload your shell
exec $SHELL -l
perlbrew --version
Install a new Perl and switch to it
# list available perls
perlbrew available
# install a specific Perl (example)
perlbrew install perl-5.38.2
# switch your current shell to that Perl
perlbrew use perl-5.38.2
# make it default for future shells
perlbrew switch perl-5.38.2
# confirm
which perl
perl -v
Install modules for that Perl (recommended: cpanminus)
perlbrew install-cpanm
cpanm --version
Each perlbrew-installed Perl has its own library path. That’s good: you avoid mixing modules compiled for different Perls.
Why perlbrew is safer than “upgrading system Perl”
- Your OS keeps using its supported Perl for system utilities.
- Your application uses a newer Perl (and you can have multiple versions side-by-side).
- Rollbacks are easy: just
perlbrew switchback.
Option C (advanced): Build Perl from source (without clobbering system Perl)
Building from source is sometimes needed for custom compile options, older distros, offline environments, or when you can’t (or don’t want to) use perlbrew. The main rule: install to a custom prefix (e.g., /opt/perl or $HOME/perl), not into /usr.
High-level process
- Install build dependencies (compiler toolchain, development headers).
- Download a Perl source tarball from perl.org.
- Configure with a safe prefix.
make,make test, thenmake install.- Update your
PATH(or use modulefiles) so your app uses the new Perl.
Example build (prefix in /opt/perl-5.38.2)
tar -xzf perl-5.38.2.tar.gz
cd perl-5.38.2
./Configure -des -Dprefix=/opt/perl-5.38.2
make -j"$(nproc)"
make test
sudo make install
# then use it explicitly:
/opt/perl-5.38.2/bin/perl -v
Common dependency pitfall: if you compile XS modules (modules with C code) later, you’ll need development tools and headers installed (and sometimes perl-devel / libperl equivalents depending on distro).
Updating CPAN modules after updating Perl
When you install a new Perl (especially via perlbrew or source), you often start with an empty site library. That’s normal. Update/install your project’s dependencies in a controlled way:
- Prefer cpanminus:
cpanmis scriptable and CI-friendly. - Avoid
sudo cpanfor app dependencies; it tends to pollute system paths and can conflict with distro packages. - Project isolation: for non-perlbrew setups, consider
local::libto keep modules in a project/user directory.
Example: install modules into a user library with local::lib
# one-time setup
perl -MCPAN -e 'install local::lib'
# initialize environment (example; local::lib prints a snippet you can eval)
perl -Mlocal::lib
# then install modules into that local lib
cpanm --local-lib=~/perl5 Some::Module Another::Module
Best practices (production-friendly)
- Don’t break the OS: keep the system Perl for the OS; use perlbrew/source-per-prefix for apps.
- Pin interpreter + dependencies per project: document the required Perl version (e.g., “Perl >= 5.34”) and install modules deterministically (lockfiles via tools like Carton if your ecosystem uses it).
- Be explicit in services: in systemd units or cron jobs, use the full path to the intended Perl (e.g.,
/opt/perl-5.38.2/bin/perl) to avoid$PATHsurprises. - Test after upgrade: run unit/integration tests, and at minimum execute a smoke test that loads your key modules.
- Plan rollback: keep the previous Perl installed until you’ve run in production for a while. perlbrew makes this trivial.
- Watch XS modules: modules with C components must be rebuilt for the new Perl (they are not generally portable across Perl builds).
Common pitfalls and how to avoid them
- Accidentally changing /usr/bin/perl: Don’t overwrite it. Use version managers or custom prefixes.
- Mixing distro modules and CPAN modules: If you install modules with
sudointo system locations, you can cause conflicts with OS package updates. Prefer isolated installs. - Confusing multiple Perls:
which perlmight differ between interactive shells, cron, and systemd. Always validate in the same context your app runs. - Forgetting to reinstall modules: A new Perl often needs dependencies reinstalled (especially XS). Automate with
cpanmand a dependency list. - Shebang mismatch: Scripts starting with
#!/usr/bin/perlwill continue to use system Perl even if you installed a newer one. For app scripts, consider#!/usr/bin/env perlor a fixed absolute path. - Assuming “latest Perl” is required: Sometimes the best move is to stay on a distro Perl and only update modules, unless you need language/runtime features or security fixes not backported.
Real-world usage patterns
- Legacy server + modern app: Keep OS Perl stable, install Perl 5.38+ via perlbrew for your service, and point systemd to that Perl.
- CI/CD matrix testing: Use multiple Perl versions in CI to ensure compatibility (e.g., lowest supported, current stable).
- Containers: Choose a base image with the Perl you want (or install via perlbrew during build), ensuring deployments are reproducible.
- Multi-tenant hosts: perlbrew per user prevents one project’s dependencies from breaking another’s.
Runnable Perl code examples
Example 1: Simple smoke test (works everywhere)
use strict;
use warnings;
print "Hello from Perl\n";
print "OK\n";
Expected output:
Hello from Perl
OK
Example 2: Check the running Perl version (useful after an upgrade)
use strict;
use warnings;
print "Perl executable: $^X\n";
print "Perl version: $^V\n";
Expected output (example; your paths/versions will differ):
Perl executable: /home/user/perl5/perlbrew/perls/perl-5.38.2/bin/perl
Perl version: v5.38.2
Example 3: Verify a core module + deterministic output (good for automation)
use strict;
use warnings;
use Digest::SHA qw(sha256_hex);
my $msg = "update-perl";
print sha256_hex($msg), "\n";
Expected output:
7a585c2b3de904804bb247e1fcd10b8b6e812207d9e7382c907ee088051dd71c
Quick decision guide
- If you administer a server and want vendor support: update via package manager (Option A).
- If you develop/deploy apps and need newer Perl features: use perlbrew (Option B).
- If you need custom builds or can’t use perlbrew: build from source with a custom prefix (Option C).
Verified Code
Executed in a sandbox to capture real output. • 13ms
7a585c2b3de904804bb247e1fcd10b8b6e812207d9e7382c907ee088051dd71c
(empty)