← All posts
May 23, 20252 min read
Linux System Setup From Scratch
A repeatable script-driven setup for a fresh Linux box: base packages, oh-my-zsh, SSH keys and jump hosts, and handy shell functions.
#linux#zsh#dotfiles
Base packages
Arch Linux
sudo pacman -Syu gcc make cmake python3 python-pip git wget nvim zsh cloudflared openssh rsync rclone
sudo chsh -s $(which zsh) $(whoami)
# Then, ensure visudo has:
# %wheel ALL=(ALL:ALL) ALLDebian / Ubuntu
# To add 'myuser' to the 'sudo' group
sudo usermod -aG sudo myuserFedora / RHEL / CentOS
# To add 'myuser' to the 'wheel' group
sudo usermod -aG wheel myuser
# Typically, the wheel group is already configured in /etc/sudoersoh-my-zsh installation
## Install oh-my-zsh
sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
## Switch to a theme that shows more useful info in the prompt
sed -i 's/^ZSH_THEME=.*/ZSH_THEME="avit"/' ~/.zshrc
## Install plugins
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-history-substring-search ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-history-substring-search
## Replace the default plugins with the following
sed -i.bak '/^plugins=.*/c\
plugins=(\
git\
zsh-syntax-highlighting\
zsh-autosuggestions\
zsh-history-substring-search\
)' ~/.zshrcGenerate SSH keys
ssh-keygen -t ed25519 -C "pc"
cat ~/.ssh/id_ed25519.pubAdd servers to your SSH config
Tip
A ProxyJump/ProxyCommand chain lets you hop through a bastion (here, a Cloudflare Tunnel) straight to an internal
cluster node in one ssh command.
mkdir -p ~/.ssh
echo "Host gila
Hostname gila.navraj.me
User gila
Port 22
ProxyCommand cloudflared access ssh --hostname %h
Host sol
Hostname sol.asu.edu
User sroy85
Port 22
ProxyJump gila" >> ~/.ssh/configA couple of zshrc functions worth stealing
mo() {
# Usage: mo <directory_name> — mkdir -p and cd into it in one go
if [ -z "$1" ]; then
echo "Usage: mo <directory_name>"
return 1
fi
if mkdir -p -- "$1"; then
if cd -- "$1"; then
return 0
else
echo "Error: Successfully created directory '$1', but could not cd into it." >&2
return 1
fi
else
echo "Error: Could not create directory '$1'." >&2
return 1
fi
}