Skip to content

Instantly share code, notes, and snippets.

@Efreak
Forked from jrandolf/install_rustup.sh
Last active January 3, 2026 00:06
Show Gist options
  • Select an option

  • Save Efreak/6f29afaefe917f6d2a8699f8d10c4779 to your computer and use it in GitHub Desktop.

Select an option

Save Efreak/6f29afaefe917f6d2a8699f8d10c4779 to your computer and use it in GitHub Desktop.
Installs rustup as a system-wide toolchain manager
#!/bin/zsh
# Rustup doesn't have an easy "system-wide" approach to installation since it
# requires $CARGO_HOME for locating the binary folder. Here, we define
# `system-wide` as requiring `sudo-only` permission, i.e. `rustup install
# toolchain ...` breaks without `sudo`.
#
# The trick is thus to somehow "envelope" Rustup in another script so that it
# uses a "system-wide" cargo home instead of the default one whenever it's
# called.
#
# This script also does some other convenient tasks such as adding the real
# Cargo home to profiles.
#
# This script is configurable:
#
# - Set `RUST_HOME` to the directory you want rustup to install toolchains and binaries to. [default=/usr/local/rust]
# - Set `CARGO_HOME` to the home directory you want Cargo to use. [default=Cargo's default]
# - Set `NO_PATH` to disable adding the Cargo home to the path. Only bash and zsh are supported. [default=false]
#
# This script must be run in sudo mode.
#
set -e
########################
# System installations #
########################
if [ -z ${RUST_HOME+x} ]; then
rust_home=/usr/local/rust
else
rust_home=$RUST_HOME
fi
# Add system-wide rust home to profile.
for profile in /etc/zsh/zshrc /etc/bash.bashrc /etc/profile.d/rustup; do
if ! grep -q "RUSTUP_HOME" $profile; then
cat <<EOF >>$profile
# Set system-wide rust home
RUSTUP_HOME=$rust_home; export RUSTUP_HOME
EOF
fi
done
# Source the profile.
# Either we are using zsh or bash
if [ -z ${BASH+x} ]; then
user_profile=$HOME/.zshrc
source /etc/zsh/zshrc
else
user_profile=$HOME/.bashrc
source /etc/bash.bashrc
fi
# Add system-wide rust home to sudo.
cat <<EOF >/etc/sudoers.d/cargo
Defaults env_keep += "RUSTUP_HOME"
EOF
# Add system-wide rust home to paths.
if [ -e /etc/paths.d ]; then
cat <<EOF >/etc/paths.d/cargo
$rust_home/bin
EOF
fi
# Install rustup.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | env CARGO_HOME=$rust_home sh -s -- -y --no-modify-path --profile minimal
# Envelope rustup.
cat <<EOF >/usr/local/bin/rustup
#!/bin/sh
CARGO_HOME=$rust_home exec $rust_home/bin/rustup "\$@"
EOF
chmod +x /usr/local/bin/rustup
######################
# User installations #
######################
# Add user Cargo home to profile.
if [ -z ${NO_PATH+x} ]; then
# Set up user bin directory.
for ppath in $user_profile /etc/profile.d/rustup /etc/zsh/zshrc /etc/bash.bashrc; do
if ! grep -q "CARGO_HOME" $ppath 2>/dev/null; then
cat <<EOF >>$ppath
# set per-user cargo home
user_cargo_home="\${XDG_DATA_HOME:+\${XDG_DATA_HOME}/cargo}"
user_cargo_home="\${user_cargo_home:-\${CARGO_HOME:-\$HOME/.cargo}}"
export CARGO_HOME=\$user_cargo_home
export PATH=\$user_cargo_home/bin:\$PATH
unset user_cargo_home
EOF
fi
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment