Mac + iTerm2 运维终端配置参考

Mac + iTerm2 运维终端配置:黑底主题 / SSH 自动角标 / zsh 增强一键还原

使用场景:Mac 上用 iTerm2,日常 SSH 到 Linux 服务器,在 tmux 里敲命令、跑 Claude Code。

配置原则:不替换、不 alias 任何原生命令lscatgrepcd 全是系统原样,手感零变化,只做纯增强。

全部配置文件化,换新设备把目录拷过去跑一个脚本即可完整还原。

一、最终效果

  • 纯黑背景 + 经典终端绿 (#00FF00)配色,深蓝、暗红都调亮过,黑底下 ls、vim、tmux 状态栏清晰可读
  • SSH 自动角标 :敲任何带 ssh 字样的命令或 alias,iTerm2 自动在屏幕右上角显示登录目标(如 root@web01.example.com),tab 标题同步;退出登录自动清空。多 tab 长时间无操作,扫一眼就知道每个 tab 连的哪台机器
  • 历史记录 20 万条:带时间戳、多 tab 实时共享、敲完立即落盘(终端崩溃不丢)、行首加空格不入历史(敲带密码的命令用)
  • Ctrl+R 模糊搜索历史(fzf):敲几个碎片关键词就能捞出几个月前那条长命令
  • 灰色自动建议 :输入时灰色提示历史匹配命令,按 接受,不按完全无感
  • 语法高亮:命令打对变绿、打错变红,回车前就知道对不对
  • Starship 提示符 :SSH 时显示绿色主机名、root 时红色警示、命令超 3 秒显示耗时、失败显示红色退出码(不用再手动 echo $?
  • 无限回滚、tmux 鼠标支持、Option 作 Meta 键(Option+B/F 按词跳光标、Claude Code 里 Option+Enter 换行)、静音铃声

二、文件结构

一个目录 5 个文件(我放在服务器 /root/mac/,也可以放 git 仓库):

复制代码
mac/
├── mac-terminal-setup.sh        # 一键安装脚本(幂等,可重复执行)
├── iterm2-ops-profile.json      # iTerm2 主题(Dynamic Profile,自动热加载)
├── iterm2-badge.zsh             # SSH 自动角标脚本
├── zshrc-ops.zsh                # zsh 增强配置
└── starship.toml                # 提示符配置

注:文中 duanshuaixing 是我的专属命名,方便多设备识别,你可以全局替换成自己的名字。

三、安装步骤

bash 复制代码
# 1. 把目录拷到 Mac(从服务器拉,或从 git 仓库 clone)
scp -rp root@你的服务器:/root/mac ~/iterm2-config

# 2. 跑安装脚本(需要已安装 Homebrew:https://brew.sh)
bash ~/iterm2-config/mac/mac-terminal-setup.sh

# 3. 新开一个 iTerm2 tab(或 source ~/.zshrc)即可看到效果

# 4. 设默认 Profile:先完全退出 iTerm2(Cmd+Q),在 Terminal.app 里执行:
defaults write com.googlecode.iterm2 "Default Bookmark Guid" "duanshuaixing-ops-dark-base"
# 再打开 iTerm2,新 tab 默认就是黑底新主题

第 4 步必须在 iTerm2 完全退出后执行,否则 iTerm2 退出时会用内存里的旧值覆盖回去。

Dynamic Profile 目录(~/Library/Application Support/iTerm2/DynamicProfiles/)是 iTerm2 实时监控的,文件放进去几秒内自动加载,不用重启。

四、配置文件全文

4.1 mac-terminal-setup.sh ------ 一键安装脚本

bash 复制代码
#!/bin/bash
# ============================================================
# duanshuaixing: Mac 终端一键配置脚本
# 用法:把 /root/mac 整个目录 scp 到 Mac 后,在该目录里执行 bash mac-terminal-setup.sh
# 幂等设计,重复执行安全,换新设备跑一遍即可完整还原
# ============================================================
set -euo pipefail
cd "$(dirname "$0")"

export HOMEBREW_NO_AUTO_UPDATE=1   # 跳过 brew 自更新,国内网络下能省很久

if ! command -v brew >/dev/null 2>&1; then
  echo "未检测到 Homebrew,请先安装: https://brew.sh"
  exit 1
fi

echo "==> 安装字体和工具(已装的会自动跳过)..."
brew install --quiet starship fzf zsh-autosuggestions zsh-syntax-highlighting || true
brew install --quiet --cask font-jetbrains-mono-nerd-font || true

echo "==> 安装 iTerm2 Dynamic Profile(自动热加载)..."
mkdir -p "$HOME/Library/Application Support/iTerm2/DynamicProfiles"
cp iterm2-ops-profile.json "$HOME/Library/Application Support/iTerm2/DynamicProfiles/"

echo "==> 安装 zsh 配置..."
cp iterm2-badge.zsh "$HOME/.iterm2-badge.zsh"
cp zshrc-ops.zsh "$HOME/.zshrc-ops"
mkdir -p "$HOME/.config"
cp starship.toml "$HOME/.config/starship.toml"

if ! grep -q 'source ~/.zshrc-ops' "$HOME/.zshrc" 2>/dev/null; then
  echo 'source ~/.zshrc-ops' >> "$HOME/.zshrc"
  echo "==> 已在 ~/.zshrc 末尾追加 source ~/.zshrc-ops"
fi

echo ""
echo "完成!最后两步手动操作:"
echo "1. 新开一个 iTerm2 tab(或执行 source ~/.zshrc)"
echo "2. 设默认 Profile:完全退出 iTerm2 (Cmd+Q) 后在 Terminal.app 执行:"
echo '   defaults write com.googlecode.iterm2 "Default Bookmark Guid" "duanshuaixing-ops-dark-base"'

4.2 iterm2-ops-profile.json ------ iTerm2 黑底主题

放到 ~/Library/Application Support/iTerm2/DynamicProfiles/ 自动生效。

关键设计:

  • Unlimited Scrollback:无限回滚,排查日志不怕翻不到
  • Mouse Reporting:tmux 里鼠标滚轮翻屏、点击切 pane(配合 tmux 的 set -g mouse on
  • Option Key Sends: 2(Esc+):Option+B/F 按词跳光标;Claude Code 里 Option+Enter 换行
  • Send Code When Idle: false:保活交给 SSH 层做(见后文 FAQ)
  • 字体 JetBrains Mono Nerd Font 14 号:0/O1/l 分明,图标正常渲染
json 复制代码
{
  "Profiles": [
    {
      "Name": "duanshuaixing-ops-dark",
      "Guid": "duanshuaixing-ops-dark-base",
      "Description": "duanshuaixing 运维专属:纯黑背景,SSH/tmux 友好,角标由 zsh 自动更新",

      "Custom Directory": "No",
      "Command": "",
      "Custom Command": "No",

      "Columns": 140,
      "Rows": 40,

      "Normal Font": "JetBrainsMonoNFM-Regular 14",
      "Use Bold Font": true,
      "Use Bright Bold": true,
      "Use Italic Font": true,
      "Horizontal Spacing": 1,
      "Vertical Spacing": 1.05,
      "Use Non-ASCII Font": false,
      "Ambiguous Double Width": false,
      "Unicode Version": 9,
      "Character Encoding": 4,

      "Terminal Type": "xterm-256color",
      "Mouse Reporting": true,
      "Mouse Reporting allow mouse wheel": true,
      "Option Key Sends": 2,
      "Right Option Key Sends": 0,

      "Scrollback Lines": 0,
      "Unlimited Scrollback": true,
      "Scrollback in Alternate Screen": false,

      "Silence Bell": true,
      "BM Growl": false,
      "Visual Bell": true,
      "Flashing Bell": false,

      "Blinking Cursor": false,
      "Cursor Type": 2,

      "Close Sessions On End": true,
      "Prompt Before Closing 2": 0,
      "Send Code When Idle": false,

      "Allow Title Setting": true,

      "Badge Text": "",
      "Badge Color": {
        "Red Component": 0.0, "Green Component": 1.0, "Blue Component": 0.0,
        "Alpha Component": 0.65, "Color Space": "sRGB"
      },
      "Badge Font": "Menlo-Bold",
      "Badge Max Width": 0.45,
      "Badge Max Height": 0.2,

      "Minimum Contrast": 0.2,
      "Transparency": 0,
      "Blur": false,

      "Foreground Color": {
        "Red Component": 0.878, "Green Component": 0.878, "Blue Component": 0.878
      },
      "Background Color": {
        "Red Component": 0.0, "Green Component": 0.0, "Blue Component": 0.0
      },
      "Bold Color": {
        "Red Component": 1.0, "Green Component": 1.0, "Blue Component": 1.0
      },
      "Cursor Color": {
        "Red Component": 0.0, "Green Component": 1.0, "Blue Component": 0.0
      },
      "Cursor Text Color": {
        "Red Component": 0.0, "Green Component": 0.0, "Blue Component": 0.0
      },
      "Selection Color": {
        "Red Component": 0.22, "Green Component": 0.32, "Blue Component": 0.47
      },
      "Selected Text Color": {
        "Red Component": 1.0, "Green Component": 1.0, "Blue Component": 1.0
      },
      "Link Color": {
        "Red Component": 0.4, "Green Component": 0.7, "Blue Component": 1.0
      },

      "Ansi 0 Color":  { "Red Component": 0.20, "Green Component": 0.20, "Blue Component": 0.20 },
      "Ansi 1 Color":  { "Red Component": 0.90, "Green Component": 0.31, "Blue Component": 0.31 },
      "Ansi 2 Color":  { "Red Component": 0.0, "Green Component": 0.80, "Blue Component": 0.0 },
      "Ansi 3 Color":  { "Red Component": 0.90, "Green Component": 0.75, "Blue Component": 0.35 },
      "Ansi 4 Color":  { "Red Component": 0.38, "Green Component": 0.62, "Blue Component": 0.94 },
      "Ansi 5 Color":  { "Red Component": 0.78, "Green Component": 0.47, "Blue Component": 0.87 },
      "Ansi 6 Color":  { "Red Component": 0.30, "Green Component": 0.78, "Blue Component": 0.78 },
      "Ansi 7 Color":  { "Red Component": 0.80, "Green Component": 0.80, "Blue Component": 0.80 },
      "Ansi 8 Color":  { "Red Component": 0.45, "Green Component": 0.45, "Blue Component": 0.45 },
      "Ansi 9 Color":  { "Red Component": 1.00, "Green Component": 0.45, "Blue Component": 0.45 },
      "Ansi 10 Color": { "Red Component": 0.0, "Green Component": 1.0, "Blue Component": 0.0 },
      "Ansi 11 Color": { "Red Component": 1.00, "Green Component": 0.88, "Blue Component": 0.45 },
      "Ansi 12 Color": { "Red Component": 0.50, "Green Component": 0.74, "Blue Component": 1.00 },
      "Ansi 13 Color": { "Red Component": 0.90, "Green Component": 0.60, "Blue Component": 1.00 },
      "Ansi 14 Color": { "Red Component": 0.45, "Green Component": 0.92, "Blue Component": 0.92 },
      "Ansi 15 Color": { "Red Component": 1.00, "Green Component": 1.00, "Blue Component": 1.00 }
    }
  ]
}

4.3 iterm2-badge.zsh ------ SSH 自动角标

不用给每台机器建 Profile:只要命令行里带 ssh 字样(alias 也算),角标自动显示登录目标。有一百个 ssh alias 也零维护。

bash 复制代码
# ============================================================
# duanshuaixing: iTerm2 自动登录角标
# 放到 Mac 的 ~/.zshrc 末尾(或 source 本文件)
#
# 效果:敲任何带 "ssh" 字样的命令/alias 时,iTerm2 在屏幕右上角
# 显示登录目标,tab 标题同步;退出登录后自动清空。
#   zhipu-ssh-claude              -> 显示 zhipu-ssh-claude
#   ssh root@web01.example.com    -> 显示 root@web01.example.com
#   ssh -p 2222 root@10.1.1.5     -> 显示 root@10.1.1.5
# ============================================================

autoload -Uz add-zsh-hook

# 设置 iTerm2 屏幕角标(OSC 1337,内容需 base64;传空串即清除)
_dsx_badge() {
  printf "\e]1337;SetBadgeFormat=%s\a" "$(printf '%s' "$1" | base64)"
}

_dsx_preexec() {
  [[ "$1" != *ssh* ]] && return
  local -a words
  words=(${(z)1})
  local name=$words[1]

  # 裸 ssh 命令:取真正的登录目标,而不是 "ssh" 本身
  if [[ $name == ssh ]]; then
    local w
    # 优先找 user@host 形式的参数
    for w in ${words[2,-1]}; do
      [[ $w == *@* ]] && { name=$w; break }
    done
    # 没有 @ 的话(用了 ssh config 别名),取第一个非选项参数
    if [[ $name == ssh ]]; then
      for w in ${words[2,-1]}; do
        [[ $w == -* ]] && continue
        name=$w; break
      done
    fi
  fi

  _dsx_badge "$name"
  printf "\e]0;%s\a" "$name"
}

_dsx_precmd() {
  _dsx_badge ""
  printf "\e]0;%s\a" ""
}

add-zsh-hook preexec _dsx_preexec
add-zsh-hook precmd  _dsx_precmd

4.4 zshrc-ops.zsh ------ zsh 增强配置

bash 复制代码
# ============================================================
# duanshuaixing: Mac 终端运维配置(zsh 部分)
# 由 mac-terminal-setup.sh 安装为 ~/.zshrc-ops,并在 ~/.zshrc 中 source
#
# 原则:不替换、不 alias 任何原生命令,手感和裸终端完全一致,
# 只做纯增强:历史记录、输入提示、提示符显示。
# ============================================================

# ---------- 历史记录:运维的命令历史就是资产 ----------
HISTFILE=~/.zsh_history
HISTSIZE=200000                 # 内存里保留 20 万条
SAVEHIST=200000                 # 文件里保留 20 万条
setopt EXTENDED_HISTORY         # 记录每条命令的时间戳和耗时
setopt INC_APPEND_HISTORY       # 敲完立即写入,不等退出(防终端崩溃丢历史)
setopt SHARE_HISTORY            # 多个 tab 之间历史实时共享
setopt HIST_IGNORE_ALL_DUPS     # 重复命令只留最新一条
setopt HIST_IGNORE_SPACE        # 行首加空格的命令不入历史(带密码的命令用)

# ---------- 补全(zsh 自带能力,只调行为不加东西)----------
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select                      # Tab 两次出菜单,方向键选
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'  # 补全忽略大小写

# ---------- 输入增强 ----------
BREW_PREFIX=$(brew --prefix)

# 自动建议:输入时灰色显示历史里匹配的命令,按 → 接受整条;不按就完全无感
source $BREW_PREFIX/share/zsh-autosuggestions/zsh-autosuggestions.zsh
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=240'

# fzf:把 Ctrl+R 升级为全屏模糊搜索历史(唯一改变原有按键行为的一项,
# 不习惯的话注释掉下面两行,Ctrl+R 立刻恢复 zsh 原生搜索)
source <(fzf --zsh)
export FZF_DEFAULT_OPTS='--height 40% --reverse --color=bg:#000000,fg:#e0e0e0,hl:#00ff00,prompt:#00ff00'

# Starship 提示符(只改提示符外观,不碰命令)
eval "$(starship init zsh)"

# ---------- iTerm2 SSH 角标 ----------
[[ -f ~/.iterm2-badge.zsh ]] && source ~/.iterm2-badge.zsh

# ---------- 语法高亮:命令存在=绿色,敲错=红色,回车前就知道对不对 ----------
# 官方要求必须放在 zshrc 最后加载
source $BREW_PREFIX/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

4.5 starship.toml ------ 提示符配置

toml 复制代码
# duanshuaixing: Starship 提示符配置(黑底运维版)
# 安装位置:~/.config/starship.toml
# 单行提示符,只显示运维真正需要的信息,不堆图标

add_newline = false
command_timeout = 1000

format = """$username$hostname$directory$git_branch$git_status$cmd_duration$status$character"""

[username]
show_always = false          # 普通用户不显示;root 或 su 到别的用户时才显示
style_user = "bold yellow"
style_root = "bold red"
format = "[$user]($style)@"

[hostname]
ssh_only = true              # 只在 SSH 会话里显示主机名,本地保持干净
style = "bold green"
format = "[$hostname]($style) "

[directory]
truncation_length = 4        # 最多显示 4 级目录
truncate_to_repo = false
style = "bold cyan"
format = "[$path]($style) "

[git_branch]
style = "purple"
format = "[$branch]($style)"

[git_status]
style = "red"
format = "[$all_status$ahead_behind]($style) "

[cmd_duration]
min_time = 3000              # 上一条命令超过 3 秒才显示耗时
style = "yellow"
format = "[$duration]($style) "

[status]
disabled = false             # 上一条命令失败时显示红色退出码,排障必备
style = "bold red"
format = "[✗$status]($style) "

[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"

五、配套的 SSH / tmux 设置(服务器侧)

1. SSH 保活 (防止长时间挂着 tmux / Claude Code 被断连),Mac 的 ~/.ssh/config

复制代码
Host *
    ServerAliveInterval 30
    ServerAliveCountMax 4

2. 远程复制直达 Mac 剪贴板(OSC52,运维刚需):

  • iTerm2:Settings → General → Selection → 勾选 "Applications in terminal may access clipboard"

  • 服务器 ~/.tmux.conf 加:

    set -g mouse on
    set -g set-clipboard on

这样在远程 tmux 里选中复制的内容直接进 Mac 剪贴板,不用鼠标跨 pane 拖选。

六、FAQ

Q: 脚本卡在 Auto-updating Homebrew...

brew 安装前的自动自更新,国内网络可能等很久。脚本里已加 HOMEBREW_NO_AUTO_UPDATE=1 跳过;手动装包时也可以 HOMEBREW_NO_AUTO_UPDATE=1 brew install xxx

Q: 角标为什么看起来比输入的文字"暗"?

角标是印在背景上的半透明水印(透明度 65%),不占行、不遮挡输出,和命令行文字不是一个东西。想更醒目就把 JSON 里 Badge ColorAlpha Component 往 1.0 调(太高会盖住文字,0.65 是可读性和醒目度的平衡点)。

Q: 不习惯 fzf 的 Ctrl+R?

注释掉 zshrc-ops.zshsource <(fzf --zsh) 那两行,Ctrl+R 立刻恢复 zsh 原生搜索。

Q: defaults write 设默认 Profile 不生效?

必须在 iTerm2 完全退出(Cmd+Q) 后执行(比如在 Terminal.app 里),否则 iTerm2 退出时会用内存里的旧值覆盖回去。

Q: ssh alias 名字里不含 "ssh" 怎么办?

角标脚本靠 [[ "$1" == *ssh* ]] 匹配。要么 alias 命名带上 ssh(如 prod-ssh-db),要么把匹配条件加宽,如 [[ "$1" == *ssh* || "$1" == jump* ]]

Q: 这套配置对服务器端生效吗?

不。历史增强、语法高亮、Starship 都装在 Mac 本地,SSH 进服务器后远端 shell 是服务器自己的配置。角标和主题是 iTerm2 层面的,全程有效。

七、换新设备还原清单

bash 复制代码
# 1. 装 Homebrew(如果是全新机器): https://brew.sh
# 2. 拷目录、跑脚本
scp -rp 旧机器或服务器:/path/to/mac ~/iterm2-config
bash ~/iterm2-config/mac/mac-terminal-setup.sh
# 3. Cmd+Q 退出 iTerm2 后设默认 Profile
defaults write com.googlecode.iterm2 "Default Bookmark Guid" "duanshuaixing-ops-dark-base"
# 4. ~/.ssh/config 加保活配置(见第五节)
相关推荐
智恒百亿31 分钟前
从开箱到跑通大模型:一台 RTX 5090 八卡服务器的部署实录(附踩坑清单)
运维·服务器
沫璃染墨34 分钟前
《从零入门Linux系统篇(三十二):文件篇·五——深入理解磁盘:从物理结构到LBA寻址》
linux·运维·服务器·系统架构·硬件架构
Songxwn1 小时前
Rack-auto 裸金属服务器自动化
运维·服务器·自动化
zlwool1 小时前
非标设备厂图纸管理选型实战
运维·服务器·erp·设备erp·非标机械
云计算磊哥@1 小时前
运维开发宝典064-CICD_Nexus3 搭建 maven 私服
运维·maven·运维开发
新时代牛马2 小时前
CFS调度源码:从 schedule() 到pick_next_entity 的vruntime 公平
linux·运维·网络
0+1112 小时前
Linux --库制作与原理
linux·运维·服务器
uxiang_blog2 小时前
Linux修改计算名字和添加删除用户名。
linux·运维·服务器
大模型码小白2 小时前
MCP协议开发实战:从零搭建AI Agent工具链
运维·人工智能·算法·机器学习·自动化