brownlu@blog:~/$
_ _ | |__ _ __ _____ ___ __ | |_ _ | '_ \| '__/ _ \ \ /\ / / '_ \| | | | | | |_) | | | (_) \ V V /| | | | | |_| | |_.__/|_| \___/ \_/\_/ |_| |_|_|\__,_|
guest @ brownlu-blog ~ /blog/dev-env-restore $
[guest@brownlu-blog] ~ $ cat dev-env-restore.md

开发环境一键恢复:Scoop + dotfiles + 自动化脚本

从软件安装到开发配置的完整自动化流程。通过 Scoop 管理应用、dotfiles 同步配置、setup 脚本一键部署,新电脑 30 分钟恢复生产环境。
📖 17 min read · 9985 chars · 2026-05-08

上一篇 个人新电脑效率配置推荐 解决了装什么软件的问题。但光有软件还不够——每台新电脑都要重新配一遍终端主题、Git 别名、Shell 快捷键,这才是最耗时的。

本文的目标是:新电脑到手,跑一条命令,30 分钟内恢复完整的开发环境。 不只是安装软件,还包括所有配置。

整体架构

新电脑开机

    ├── ① 安装 Scoop(包管理器)
    │       │
    │       ├── ② 配置国内加速(xrgzs/scoop + GH_PROXY)
    │       │
    │       └── ③ 安装所有软件(scoop install ...)

    └── ④ 执行 dotfiles 配置脚本

            ├── Git 配置(user / aliases / 默认分支)
            ├── PowerShell Profile(aliases / oh-my-posh)
            ├── Nushell 配置(config.nu / env.nu)
            ├── Windows Terminal 主题
            └── 系统设置(文件扩展名显示等)

核心思路:软件是标准化的,配置是个性化的。 Scoop 负责前者,dotfiles 负责后者。

一、setup.ps1:一键安装软件

这是整个流程的入口。脚本内容已经在上一篇文章中创建并部署到了 /scripts/setup.ps1

irm https://lug3zz.github.io/scripts/setup.ps1 | iex

脚本执行的步骤:

  1. 检测并安装 Scoop — 使用 Gitee 镜像源,避免 GitHub 超时
  2. 配置加速 — 切换 xrgzs/scoop,设置 GH_PROXY
  3. 添加 bucket — main、extras、dorado、spc、nerd-fonts
  4. 分类安装软件 — 终端、开发、辅助、效率、远程、字体
  5. 清理缓存 — 释放磁盘空间

建议将脚本内容 fork 到你自己的仓库,修改为你实际需要安装的软件列表。不要直接依赖别人的脚本执行未知内容。

二、Git 配置:一次设置,永久生效

装好 Git 后第一件事就是配置。以下是最小可用配置:

# 身份信息
git config --global user.name "YourName"
git config --global user.email "your@email.com"

# 默认分支名
git config --global init.defaultBranch main

# 拉取策略(避免合并污染历史)
git config --global pull.rebase true

# 常用别名
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.last "log -1 HEAD"

# 编辑器
git config --global core.editor "code --wait"

# 凭据存储(避免每次 push 都输密码)
git config --global credential.helper manager-core

# 换行符(Windows 上提交时转 LF,检出时转 CRLF)
git config --global core.autocrlf true

配置后效果:

# git lg — 漂亮的图形化日志
* a1b2c3d (HEAD -> main) fix: 修复登录问题
* e4f5g6h feat: 添加用户注册
* i7j8k9l docs: 更新 README

# git st — 等同于 git status
# git last — 查看最近一次提交

三、PowerShell Profile:你的 Shell 灵魂

PowerShell Profile 是每次启动 Shell 时自动执行的脚本,位置在 $PROFILE(本机路径 ~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1)。

本机 Profile 配置

# Microsoft.PowerShell_profile.ps1

# --- 启动时清屏 + 主题 ---
cls
oh-my-posh init pwsh --config "$env:LOCALAPPDATA\Programs\oh-my-posh\themes\catppuccin_mocha.omp.json" | Invoke-Expression
fastfetch

# --- 常用别名 ---
function ll { ls -l @args }
function la { ls -Force @args }
function .. { Set-Location .. }
function ... { Set-Location ../.. }
function dev { Set-Location ~\Documents\项目 }
function g { git @args }

# --- Scoop 别名 ---
function sci { scoop install @args }
function ss { scoop search @args }
function su { scoop update @args }
function sr { scoop reset @args }
function sc { scoop cache rm @args }

# --- 系统信息 ---
function sys { fastfetch }

# --- 快速编辑配置 ---
function edit-profile { nvim $PROFILE }
function reload-profile { & $PROFILE }

# --- PSReadLine 智能提示 ---
Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -PredictionViewStyle ListView

try { Import-Module Terminal-Icons -ErrorAction Stop } catch {}

# --- 移除冲突别名,重定义常用命令 ---
@('cd','ls','rm','cp','mv','cat','mkdir','history','echo') | ForEach-Object {
    if (Get-Alias $_ -ErrorAction SilentlyContinue) {
        Remove-Item "Alias:$_" -Force -ErrorAction SilentlyContinue
    }
}

function ls {
    $showAll = $false; $rest = @()
    foreach ($arg in $args) {
        if ($arg -match '^-[a-zA-Z]*a[a-zA-Z]*$') { $showAll = $true }
        else { $rest += $arg }
    }
    if ($showAll) { Get-ChildItem -Force @rest }
    else          { Get-ChildItem @rest }
}
function touch { param([string]$Path); New-Item -ItemType File -Force -Path $Path | Out-Null }
function mkdir { param([string]$Path); New-Item -ItemType Directory -Force -Path $Path | Out-Null }
function cat  { param([string]$Path); Get-Content -Path $Path -Raw }
function rm   {
    param([string]$Path, [switch]$r, [switch]$f, [switch]$rf, [switch]$fr)
    Remove-Item -Path $Path -Recurse:($r -or $rf -or $fr) -Force:($f -or $rf -or $fr)
}

# --- grep:文本搜索,支持管道 ---
function grep {
    param([string]$Pattern, [string]$Path)
    if ($Path) { Select-String -Pattern $Pattern -Path $Path }
    else       { $input | Select-String -Pattern $Pattern }
}

# --- cd:支持无参数回到 ~,支持 /d/path 格式 ---
function cd {
    if ($args.Count -eq 0) { Set-Location ~; return }
    $Path = $args[0]
    if ($Path -match '^/([a-zA-Z])/(.*)$') {
        Set-Location -Path "${($Matches[1]).ToUpper()}:\$($Matches[2] -replace '/', '\')"
    } else { Set-Location -Path $Path }
}

# --- 历史记录 ---
function history { param([int]$Count = 100)
    Get-Content (Get-PSReadLineOption).HistorySavePath | Select-Object -Last $Count
}

# --- 工具函数 ---
function echo  { Write-Output @args }
function which { param([string]$cmd) (Get-Command $cmd -ErrorAction SilentlyContinue).Source }
function reload { . $PROFILE; Write-Host "Profile reloaded." -ForegroundColor Green }
function profile-time {
    $a = (Measure-Command { powershell -NoProfile -Command "exit" }).TotalMilliseconds
    $b = (Measure-Command { powershell -Command "exit" }).TotalMilliseconds
    Write-Host "加载耗时: $([math]::Round($b - $a, 1))ms"
}

# --- zoxide 智能跳转 ---
Invoke-Expression (& { (zoxide init powershell | Out-String) })

应用配置

# 确保执行策略允许运行
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

# 检查 $PROFILE 路径
echo $PROFILE

# 编辑配置文件
nvim $PROFILE

# 保存后重新加载
. $PROFILE

四、Nushell 配置:现代化的 Shell 体验

Nushell 的特别之处在于它的输出是结构化数据,而非纯文本。这意味着你可以直接对命令输出进行过滤、排序、统计。

config.nu

# ~/.config/nushell/config.nu

$env.config = {
    show_banner: true
    rm: {
        always_trash: true
    }
    shell_integration: {
        osc2: true
        osc7: true
        osc8: true
        osc133: true
        osc633: true
    }
}

# 常用别名
alias ll = ls -l
alias la = ls -a
alias g = git
alias v = nvim
alias cat = bat

# 快捷跳转
alias .. = cd ..
alias dev = cd ~/dev
alias dl = cd ~/Downloads

env.nu

# ~/.config/nushell/env.nu

$env.PATH = ($env.PATH | split row (char esep))

# 编辑器
$env.EDITOR = "nvim"
$env.VISUAL = "nvim"

# Git 相关
$env.GIT_SSH_COMMAND = "ssh -o StrictHostKeyChecking=no"

Nushell 和 PowerShell 可以共存。日常开发用 PowerShell(更好的 Windows 集成和 Scoop 支持),数据处理和快速查询用 Nushell(结构化管道)。

五、Windows Terminal 配置

Windows Terminal 的配置文件是 settings.json,位于 %LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\

推荐的 settings.json 配置

{
    "$schema": "https://aka.ms/terminal-profiles-schema",
    "defaultProfile": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
    "theme": "dark",
    "launchMode": "maximized",
    "alwaysShowTabs": true,
    "showTabsInTitlebar": true,
    "requestedTheme": "system",
    "profiles": {
        "defaults": {
            "font": {
                "face": "Maple Mono NF CN",
                "size": 12
            },
            "cursorShape": "bar",
            "cursorHeight": 75,
            "padding": "12",
            "opacity": 95,
            "useAcrylic": true,
            "acrylicOpacity": 80,
            "closeOnExit": "graceful",
            "startingDirectory": "%USERPROFILE%"
        },
        "list": [
            {
                "guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
                "hidden": false,
                "name": "PowerShell",
                "source": "Windows.Terminal.PowershellCore",
                "commandline": "pwsh.exe"
            },
            {
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
                "hidden": false,
                "name": "Windows PowerShell",
                "commandline": "powershell.exe"
            },
            {
                "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
                "hidden": false,
                "name": "Git Bash",
                "commandline": "\"%SCOOP%\\apps\\git\\current\\usr\\bin\\bash.exe\" -i -l",
                "icon": "%SCOOP%\\apps\\git\\current\\usr\\share\\git\\git-for-windows.ico"
            }
        ]
    },
    "keybindings": [
        { "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+c" },
        { "command": "paste", "keys": "ctrl+v" },
        { "command": "find", "keys": "ctrl+shift+f" },
        { "command": "closeTab", "keys": "ctrl+w" },
        { "command": "newTab", "keys": "ctrl+t" },
        { "command": "nextTab", "keys": "ctrl+tab" },
        { "command": "prevTab", "keys": "ctrl+shift+tab" }
    ]
}

关键配置说明:

配置项作用
font.face设置为 Maple Mono NF CN,支持连字和中文字符
cursorShape: bar竖线光标,Vim 风格
opacity + useAcrylic半透明毛玻璃效果
startingDirectory默认启动到用户目录
closeOnExit: graceful正常退出时关闭窗口

六、dotfiles 管理:配置即代码

把所有配置文件放在一个 Git 仓库中,这就是你的 dotfiles

推荐的目录结构

dotfiles/
├── README.md
├── install.ps1          # 一键部署脚本
├── git/
│   └── .gitconfig       # Git 全局配置
├── powershell/
│   └── Microsoft.PowerShell_profile.ps1
├── nushell/
│   ├── config.nu
│   └── env.nu
├── terminal/
│   └── settings.json    # Windows Terminal 配置
└── scripts/
    ├── setup.ps1        # Scoop 安装脚本
    └── aliases.ps1      # 额外别名

部署脚本 install.ps1

# install.ps1 — 从 dotfiles 仓库部署配置

$DOTFILES = Split-Path -Parent $MyInvocation.MyCommand.Path

Write-Host "Deploying dotfiles..." -ForegroundColor Cyan

# Git 配置
Write-Host "`n[1/4] Configuring Git..." -ForegroundColor Yellow
Copy-Item "$DOTFILES/git/.gitconfig" "$env:USERPROFILE/.gitconfig" -Force

# PowerShell Profile
Write-Host "[2/4] Configuring PowerShell..." -ForegroundColor Yellow
$psProfileDir = Join-Path $env:USERPROFILE ".config/powershell"
New-Item -ItemType Directory -Path $psProfileDir -Force | Out-Null
Copy-Item "$DOTFILES/powershell/Microsoft.PowerShell_profile.ps1" "$psProfileDir/" -Force

# Nushell 配置
Write-Host "[3/4] Configuring Nushell..." -ForegroundColor Yellow
$nuDir = Join-Path $env:USERPROFILE ".config/nushell"
New-Item -ItemType Directory -Path $nuDir -Force | Out-Null
Copy-Item "$DOTFILES/nushell/config.nu" "$nuDir/" -Force
Copy-Item "$DOTFILES/nushell/env.nu" "$nuDir/" -Force

# Windows Terminal(可选,需要手动处理 GUID)
Write-Host "[4/4] Configuring Windows Terminal..." -ForegroundColor Yellow
$wtDir = "$env:LOCALAPPDATA/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState"
if (Test-Path $wtDir) {
    Copy-Item "$DOTFILES/terminal/settings.json" "$wtDir/" -Force
    Write-Host "  Windows Terminal config deployed." -ForegroundColor Green
} else {
    Write-Host "  Windows Terminal not found, skipping." -ForegroundColor DarkGray
}

Write-Host "`nDone! Restart your terminal to apply changes." -ForegroundColor Cyan

七、一键恢复完整环境

把以上所有步骤串联起来,最终的一条命令流程:

# 1. 克隆 dotfiles
git clone https://github.com/yourname/dotfiles.git ~/dotfiles
cd ~/dotfiles

# 2. 运行安装脚本
.\install.ps1

# 3. 安装软件(如未运行过 setup.ps1)
.\scripts\setup.ps1

# 4. 重启终端

或者更简洁的版本:

irm https://github.com/yourname/dotfiles/raw/main/bootstrap.ps1 | iex

bootstrap.ps1 负责克隆 dotfiles 仓库、执行 install.ps1、运行 setup.ps1、清理临时文件。

八、维护与更新

dotfiles 仓库需要持续维护:

# 更新配置后同步
cd ~/dotfiles
git add -A
git commit -m "update: 新的 oh-my-posh 主题配置"
git push

# 在其他机器上拉取最新配置
cd ~/dotfiles
git pull

# 重新部署
.\install.ps1

版本控制注意事项

  • 不要提交 .gitconfig 中的用户名邮箱(不同机器可能不同),使用 [include] 分离
  • 不要提交 API Key、Token 等敏感信息
  • 使用 .gitignore 排除临时文件
# .gitignore
*.ps1xml
.cache/
.env

九、进阶:环境变量管理

不同的开发环境需要不同的环境变量。推荐用 PowerShell Profile 动态加载:

# 根据目录自动设置环境变量
function Set-Env {
    $path = Get-Location

    if ($path -match "project-a") {
        $env:API_URL = "https://api.project-a.com"
        $env:DEBUG = "true"
    }
    elseif ($path -match "project-b") {
        $env:API_URL = "https://api.project-b.com"
        $env:DEBUG = "false"
    }
}

# 每次 cd 后自动调用
$env:PATH += ";$env:USERPROFILE\scripts"

从软件安装到配置同步,整套流程的核心是 可重复

  • Scoop 保证软件版本一致
  • dotfiles 保证配置一致
  • 脚本保证流程可重复

当你能在 30 分钟内让一台新电脑恢复到和原来一模一样时,重装系统就不再是恐惧,而是一次刷新。

本文提到的setup.ps1 已部署在 本博客的 scripts 目录 中,dotfiles 仓库和 install.ps1 需要你自己创建和维护。

下篇预告:新电脑配置系列的第三篇 —— 终端进阶:Nushell 结构化数据管道与实战技巧

tags: efficiencydotfilesautomationwindows
series: 新电脑配置 — Part 2
← 磨刀不误砍柴工,Windows 新电脑配置,助你高效率完成工作 最后一次配置 Linux →
← back to /blog | ↓ download .md
[x]