Shell 环境搭建
第1章:Shell 环境搭建
工欲善其事,必先利其器。在深入学习 Linux Shell 之前,搭建一套顺手的开发环境至关重要——选对 Shell、配好终端复用器、掌握编辑器基础,能让你的效率提升数倍。本章从零开始,带你构建一套专业级的 Shell 工作环境。
1.1 Shell 选型:bash vs zsh vs fish
Linux 下常用的交互式 Shell 有三种主流选择:bash(Bourne Again Shell)、zsh(Z Shell)和 fish(Friendly Interactive Shell)。它们各有侧重,下表从多个维度进行对比:
| 特性 | bash | zsh | fish |
|---|---|---|---|
| 默认系统 Shell | 大多数 Linux 发行版 | macOS 10.15+ | 无(需手动安装) |
| 脚本兼容性 | POSIX 完全兼容 | 兼容 bash(大部分) | 不兼容 POSIX,语法独立 |
| 自动补全 | 基础(bash-completion 扩展) | 强大,支持上下文感知 | 开箱即用,最智能 |
| 提示符定制 | PS1 变量 | PROMPT / oh-my-zsh / starship | 内置配置工具 |
| 插件生态 | 有限(bash-it) | 丰富(oh-my-zsh, zinit) | fisher / oh-my-fish |
| 历史记录 | ~/.bash_history | 共享历史,更强大 | 按目录分类历史 |
| 学习曲线 | 平缓,资料丰富 | 中等,配置稍复杂 | 最低,新手友好 |
| 推荐场景 | 脚本编写、服务器管理 | 日常开发、高度定制 | 交互式使用,新手入门 |
建议: 日常交互使用 zsh(配合 oh-my-zsh),脚本编写始终使用 bash(#!/bin/bash)以确保可移植性。fish 适合完全新手的交互使用,但脚本不兼容 POSIX,不推荐用于服务器。
1.2 安装与切换 Shell
使用 cat /etc/shells 查看系统中已安装的所有合法 Shell,使用 echo $SHELL 查看当前正在使用的 Shell。
# 查看系统可用的 Shell 列表
cat /etc/shells
# 输出示例:
# /bin/sh
# /bin/bash
# /usr/bin/zsh
# /usr/bin/fish
# 查看当前 Shell
echo $SHELL
# /bin/bash
# 查看当前 Shell 版本
bash --version
zsh --version
# 安装 zsh(Ubuntu/Debian)
sudo apt install -y zsh
# 安装 fish
sudo apt install -y fish
# 切换默认 Shell 为 zsh(永久生效,需要重新登录)
chsh -s $(which zsh)
# 切换当前会话的 Shell(临时)
exec zsh
# 验证切换结果
echo $SHELL
注意:
chsh修改的是登录 Shell,需要退出并重新登录才能生效。在某些系统(如 Ubuntu)中,chsh要求输入当前用户密码。切换后请确认/etc/shells中包含新 Shell 的路径,否则chsh会拒绝切换。
1.3 bash 配置:.bashrc 与 .bash_profile
bash 有多个配置文件,分别在不同场景下加载,理解它们的区别是避免配置失效的关键:
- ~/.bash_profile — 登录 Shell 启动时读取(SSH 登录、控制台登录)。通常在这里设置 PATH 和环境变量
- ~/.bashrc — 非登录交互式 Shell 启动时读取(打开新终端窗口)。别名、函数、提示符设置放这里
- ~/.bash_logout — 登录 Shell 退出时执行
- /etc/profile — 系统级登录 Shell 配置,所有用户生效
# ~/.bash_profile 推荐内容:让登录 Shell 也读取 .bashrc
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
# 设置 PATH(追加自定义路径)
export PATH="$HOME/.local/bin:$HOME/bin:$PATH"
# ~/.bashrc 推荐结构:
# 1. 环境变量
export EDITOR=vim
export LANG=en_US.UTF-8
# 2. 别名
alias ll='ls -alF --color=auto'
alias la='ls -A'
alias grep='grep --color=auto'
alias ..='cd ..'
alias ...='cd ../..'
# 3. 自定义 PS1 提示符
# \u = 用户名, \h = 主机名, \w = 当前目录
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# 4. 历史记录设置
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoredups:erasedups # 忽略重复命令
shopt -s histappend # 追加而非覆盖历史文件
# 5. 加载 bash-completion(如果安装)
if [ -f /usr/share/bash-completion/bash_completion ]; then
source /usr/share/bash-completion/bash_completion
fi
# 修改后立即生效(无需重启终端)
source ~/.bashrc
1.4 zsh + oh-my-zsh / starship
安装 oh-my-zsh
# 安装 oh-my-zsh(官方安装脚本)
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 安装后编辑 ~/.zshrc
# 修改主题
ZSH_THEME="agnoster" # 常用:robbyrussell, agnoster, powerlevel10k
# 安装 zsh-autosuggestions 插件(命令历史自动补全)
git clone https://github.com/zsh-users/zsh-autosuggestions \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
# 安装 zsh-syntax-highlighting 插件(命令语法高亮)
git clone https://github.com/zsh-users/zsh-syntax-highlighting \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
# 在 ~/.zshrc 中启用插件(注意:多个插件用空格分隔)
plugins=(
git
docker
kubectl
zsh-autosuggestions
zsh-syntax-highlighting
z # 目录跳转(autojump 替代)
extract # 智能解压(x file.tar.gz)
colored-man-pages
)
# 使配置生效
source ~/.zshrc
使用 starship 跨 Shell 提示符
starship 是一款用 Rust 编写的极速跨 Shell 提示符,支持 bash/zsh/fish,无需额外配置即可显示 Git 状态、语言版本、Docker 上下文等信息。
# 安装 starship
curl -sS https://starship.rs/install.sh | sh
# 在 ~/.bashrc 末尾添加(bash)
eval "$(starship init bash)"
# 在 ~/.zshrc 末尾添加(zsh)
eval "$(starship init zsh)"
# 在 ~/.config/fish/config.fish 添加(fish)
starship init fish | source
# starship 配置文件位置
mkdir -p ~/.config
# 编辑 ~/.config/starship.toml
# 示例配置
cat >> ~/.config/starship.toml
## 1.5 tmux 终端复用器完整指南
**tmux**(Terminal Multiplexer)让你在一个终端窗口中运行多个会话和窗格,SSH 断线后程序仍在后台运行。掌握 tmux 是服务器运维和远程开发的必备技能。
### 安装与基本概念
```bash
# 安装 tmux
sudo apt install -y tmux # Ubuntu/Debian
sudo dnf install -y tmux # Fedora/RHEL
sudo pacman -S tmux # Arch Linux
# tmux 三层结构:
# Session(会话) > Window(窗口) > Pane(窗格)
# 启动一个新会话
tmux
# 启动并命名会话
tmux new-session -s myproject
# 简写
tmux new -s myproject
Prefix Key 与常用快捷键
tmux 的所有快捷键都以 Prefix Key 开头,默认是 Ctrl+b。先按 Prefix,再按功能键。
# === 会话管理 ===
tmux new -s work # 新建名为 work 的会话
tmux ls # 列出所有会话
tmux attach -t work # 重新连接 work 会话(简写:tmux a -t work)
tmux kill-session -t work # 删除会话
# Prefix + d → 暂时离开(detach)当前会话,程序继续运行
# Prefix + $ → 重命名当前会话
# Prefix + s → 交互式切换会话列表
# === 窗口管理 ===
# Prefix + c → 新建窗口
# Prefix + , → 重命名当前窗口
# Prefix + n → 切换到下一个窗口
# Prefix + p → 切换到上一个窗口
# Prefix + 0~9 → 切换到指定编号窗口
# Prefix + w → 窗口列表(交互式)
# Prefix + & → 关闭当前窗口
# === 窗格管理(分屏)===
# Prefix + % → 垂直分割(左右两个窗格)
# Prefix + " → 水平分割(上下两个窗格)
# Prefix + 方向键 → 切换窗格
# Prefix + z → 最大化/还原当前窗格
# Prefix + x → 关闭当前窗格
# Prefix + { → 向左移动窗格
# Prefix + } → 向右移动窗格
# Prefix + Alt+方向键 → 调整窗格大小
# === 复制模式(滚动历史)===
# Prefix + [ → 进入复制模式,可用方向键/Page Up/Down 滚动
# q → 退出复制模式
~/.tmux.conf 推荐配置
# ~/.tmux.conf — 推荐配置
# 修改 Prefix 为 Ctrl+a(更顺手)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# 鼠标支持(点击切换窗格,滚轮滚动)
set -g mouse on
# 窗格分割快捷键(更直觉)
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %
# 新建窗口时保持当前目录
bind c new-window -c "#{pane_current_path}"
# vim 风格窗格切换
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# 256 色支持
set -g default-terminal "screen-256color"
set -ag terminal-overrides ",xterm-256color:RGB"
# 状态栏样式
set -g status-bg colour235
set -g status-fg colour136
set -g status-left "#[fg=green]#S "
set -g status-right "#[fg=yellow]%Y-%m-%d %H:%M"
set -g status-right-length 50
# 窗口编号从 1 开始(而非 0)
set -g base-index 1
setw -g pane-base-index 1
# 历史记录行数
set -g history-limit 50000
# 重新加载配置(无需退出 tmux)
bind r source-file ~/.tmux.conf \; display-message "Config reloaded!"
生产技巧: 每次连接服务器后立即执行
tmux attach || tmux new -s main:如果有已存在的会话则直接连接,否则新建名为 main 的会话。把这行写进本地的~/.ssh/config的RemoteCommand,可以实现 SSH 登录后自动进入 tmux。
1.6 vim / nano 编辑器基础
服务器上通常没有图形界面,掌握 vim 是 Linux 运维人员的必备技能。vim 采用模式化编辑,初学者需要先理解模式切换逻辑。
vim 三种核心模式
# vim 模式切换
# 普通模式(Normal) → 插入模式(Insert):按 i / a / o
# 插入模式 → 普通模式:按 Esc
# 普通模式 → 命令行模式(Command):按 :
# === 普通模式:移动 ===
# h j k l → 左下上右
# w / b → 下一个单词 / 上一个单词
# 0 / $ → 行首 / 行尾
# gg / G → 文件首行 / 末行
# Ctrl+f/b → 向下/上翻页
# :42 → 跳到第 42 行
# === 普通模式:编辑 ===
# dd → 删除(剪切)当前行
# yy → 复制当前行
# p / P → 粘贴到光标后/前
# u → 撤销
# Ctrl+r → 重做
# x → 删除光标处字符
# r → 替换光标处字符
# === 普通模式:搜索 ===
# /pattern → 向下搜索(n 下一个,N 上一个)
# ?pattern → 向上搜索
# :%s/old/new/g → 全文替换
# === 命令行模式:保存退出 ===
# :w → 保存
# :q → 退出(未修改时)
# :wq 或 :x → 保存并退出
# :q! → 强制退出(放弃修改)
最小化 vimrc 配置
# ~/.vimrc — 最小化但实用的配置
cat > ~/.vimrc :w
inoremap :wa
EOF
echo "vimrc created!"
nano 快速上手: 如果 vim 暂时太难,nano 是更友好的选择。
nano filename打开文件,底部显示所有快捷键(^表示 Ctrl)。Ctrl+X退出,Ctrl+O保存,Ctrl+W搜索。
1.7 包管理器:apt / dnf / pacman
不同 Linux 发行版使用不同的包管理器。以下是三大主流包管理器的常用操作对照:
# === apt(Ubuntu / Debian / Kali)===
sudo apt update # 更新软件包索引
sudo apt upgrade # 升级所有已安装包
sudo apt install -y vim git curl # 安装软件包
sudo apt remove vim # 卸载(保留配置)
sudo apt purge vim # 彻底卸载(删配置)
sudo apt autoremove # 清理孤立依赖
apt search "text editor" # 搜索包
apt show vim # 显示包详情
dpkg -l | grep vim # 列出已安装包(过滤)
# === dnf(Fedora / RHEL / CentOS 8+)===
sudo dnf check-update # 检查更新
sudo dnf upgrade # 升级所有包
sudo dnf install -y vim git curl # 安装软件包
sudo dnf remove vim # 卸载
sudo dnf autoremove # 清理孤立依赖
dnf search vim # 搜索包
dnf info vim # 显示包详情
dnf list installed | grep vim # 列出已安装包
# === pacman(Arch Linux / Manjaro)===
sudo pacman -Sy # 同步包数据库
sudo pacman -Syu # 完整系统升级
sudo pacman -S vim git curl # 安装软件包
sudo pacman -R vim # 卸载(保留依赖)
sudo pacman -Rs vim # 卸载(同时移除不需要的依赖)
pacman -Ss vim # 搜索包
pacman -Si vim # 显示包详情
pacman -Q | grep vim # 列出已安装包
# === 通用工具(所有发行版)===
# snap(Canonical 出品,沙盒应用)
sudo snap install code --classic # 安装 VS Code
# flatpak(跨发行版桌面应用)
flatpak install flathub org.gimp.GIMP
1.8 dotfiles 管理:版本控制最佳实践
dotfiles 是以 . 开头的配置文件(~/.bashrc、~/.tmux.conf 等)。将它们纳入 Git 版本控制,可以在新机器上一键还原你的完整工作环境。
方法一:Git 裸仓库(推荐)
# 初始化裸仓库,存放在 ~/.dotfiles
git init --bare $HOME/.dotfiles
# 创建别名(加入 ~/.bashrc 或 ~/.zshrc)
alias dotfiles='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
# 不追踪未被明确添加的文件(防止 HOME 目录被污染)
dotfiles config --local status.showUntrackedFiles no
# 远程仓库(GitHub)
dotfiles remote add origin [email protected]:yourname/dotfiles.git
# 添加并提交配置文件
dotfiles add ~/.bashrc ~/.zshrc ~/.tmux.conf ~/.vimrc
dotfiles commit -m "Initial dotfiles setup"
dotfiles push -u origin main
# === 在新机器上恢复 ===
# 1. 克隆裸仓库
git clone --bare [email protected]:yourname/dotfiles.git $HOME/.dotfiles
# 2. 添加别名
alias dotfiles='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
# 3. 检出文件到 HOME 目录
dotfiles checkout
方法二:GNU stow(符号链接管理器)
# 安装 GNU stow
sudo apt install -y stow
# 目录结构示例:~/dotfiles/
# dotfiles/
# ├── bash/
# │ └── .bashrc
# ├── vim/
# │ └── .vimrc
# └── tmux/
# └── .tmux.conf
mkdir -p ~/dotfiles/bash ~/dotfiles/vim ~/dotfiles/tmux
mv ~/.bashrc ~/dotfiles/bash/
mv ~/.vimrc ~/dotfiles/vim/
mv ~/.tmux.conf ~/dotfiles/tmux/
# 使用 stow 创建符号链接(从 ~/dotfiles 目录运行)
cd ~/dotfiles
stow bash # 创建 ~/.bashrc -> ~/dotfiles/bash/.bashrc
stow vim # 创建 ~/.vimrc -> ~/dotfiles/vim/.vimrc
stow tmux # 创建 ~/.tmux.conf -> ~/dotfiles/tmux/.tmux.conf
# 将 ~/dotfiles 纳入 Git 管理
cd ~/dotfiles
git init
git remote add origin [email protected]:yourname/dotfiles.git
git add .
git commit -m "Add dotfiles via stow"
git push -u origin main
1.9 查阅帮助文档:man / help / tldr
Linux 自带完整的文档系统,学会查阅文档比死记硬背命令更重要。
# === man(Manual Pages)===
man ls # 查看 ls 命令的完整手册
man 5 passwd # 查看 Section 5(文件格式)的 passwd
man -k "copy file" # 关键词搜索手册页(等同 apropos)
# man 手册中的快捷键:
# /pattern → 搜索,n/N 下一个/上一个
# q → 退出
# === --help(快速参考)===
ls --help # 内置帮助,比 man 更简洁
git commit --help # 大多数程序都支持
# === type / which(找命令位置)===
type ls # 判断是别名、内置命令还是外部程序
which python3 # 显示外部命令的路径
whereis bash # 显示二进制、源码和 man 文件的位置
# === tldr(Too Long; Didn't Read)===
# 安装 tldr(社区维护的简洁示例集合)
sudo npm install -g tldr
# 或
pip install tldr
tldr tar # 显示 tar 的常用示例(比 man 更直觉)
tldr find # find 的常用用法
tldr ssh # ssh 的常用示例
# === info(GNU 文档系统)===
info coreutils # GNU 核心工具的详细文档
info bash # Bash 完整参考手册
章节总结: 你现在已经拥有了专业 Shell 工作环境的完整知识框架:zsh + oh-my-zsh 提供强大的交互体验,tmux 让你的会话永不丢失,vim 让你在任何服务器上都能高效编辑,dotfiles 管理确保环境可复现。下一章将深入探索 Linux 文件系统的内部结构。
上一章
← 前言
下一章
第2章:文件系统深度 →