<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Windows on Jiangwan&#39;s Blog</title>
        <link>https://jiangwan.ink/tags/windows/</link>
        <description>Recent content in Windows on Jiangwan&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Mon, 30 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jiangwan.ink/tags/windows/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>解决 Windows 环境下 Git SSH Permission denied 报错</title>
        <link>https://jiangwan.ink/p/git-windows-ssh-permission-denied/</link>
        <pubDate>Mon, 30 Mar 2026 00:00:00 +0000</pubDate>
        
        <guid>https://jiangwan.ink/p/git-windows-ssh-permission-denied/</guid>
        <description>&lt;h2 id=&#34;一现象描述&#34;&gt;一、现象描述
&lt;/h2&gt;&lt;p&gt;在 Windows 环境下配置 GitHub SSH 密钥时，常常会遇到一个充满迷惑性的报错现象。当我们在终端直接测试 SSH 连接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh -T git@github.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;终端会正常返回欢迎信息，证明密钥配置无误：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hi your_username! You&amp;#39;ve successfully authenticated...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但紧接着执行 &lt;code&gt;git clone&lt;/code&gt; 或 &lt;code&gt;git push&lt;/code&gt; 命令时，却直接报错拒绝访问：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git@github.com: Permission denied (publickey).
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;fatal: Could not read from remote repository.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;二问题排查&#34;&gt;二、问题排查
&lt;/h2&gt;&lt;p&gt;现象表现为同一台电脑对同一份密钥的读取结果前后矛盾。为了确认 Git 在执行网络请求时到底发生了什么，我们可以开启 Git 的 SSH 调试模式。在终端临时注入环境变量，强制输出 Git 底层的 SSH 调用日志：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GIT_SSH_COMMAND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ssh -v&amp;#34;&lt;/span&gt; git clone git@github.com:your-name/your-repo.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过详细日志可以观察到，&lt;code&gt;git clone&lt;/code&gt; 并没有调用系统默认的 SSH 程序，也没有去正确的 &lt;code&gt;~/.ssh&lt;/code&gt; 目录下寻找刚刚配置好的私钥。&lt;/p&gt;
&lt;h2 id=&#34;三原因分析&#34;&gt;三、原因分析
&lt;/h2&gt;&lt;p&gt;这个问题的核心在于：Windows 系统中同时存在两个互不相通的 SSH 程序。&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  graph TD
    A[终端环境] --&amp;gt; B{执行指令}
    B --&amp;gt;|ssh -T| C[Windows 原生 OpenSSH]
    B --&amp;gt;|git clone| D[Git 自带内部 SSH]
    
    C --&amp;gt;|读取 C:\Users\用户名\.ssh| E[找到私钥]
    E --&amp;gt; F[连接 GitHub 成功]
    
    D --&amp;gt;|MSYS2 模拟环境| G[路径解析偏差 / 无法读取 ssh-agent]
    G --&amp;gt; H[找不到私钥]
    H --&amp;gt; I[Permission denied]
&lt;/pre&gt;

&lt;h3 id=&#34;1-windows-原生-openssh&#34;&gt;1. Windows 原生 OpenSSH
&lt;/h3&gt;&lt;p&gt;从 Windows 10 开始，微软内置了一套原生的 OpenSSH 工具，路径为 &lt;code&gt;C:\Windows\System32\OpenSSH\ssh.exe&lt;/code&gt;。执行 &lt;code&gt;ssh -T&lt;/code&gt; 时，系统默认唤醒的是这个原生程序。它能准确识别当前 Windows 用户的 &lt;code&gt;~/.ssh&lt;/code&gt; 目录并读取私钥，因此测试顺利通过。&lt;/p&gt;
&lt;h3 id=&#34;2-git-for-windows-自带-ssh&#34;&gt;2. Git for Windows 自带 SSH
&lt;/h3&gt;&lt;p&gt;安装 Git 时，为了兼容旧版 Windows，Git 官方打包了一个专属的 SSH 程序，路径通常在 &lt;code&gt;C:\Program Files\Git\usr\bin\ssh.exe&lt;/code&gt;。执行 &lt;code&gt;git clone&lt;/code&gt; 时，Git 会强制调用自带的内部 SSH。由于该程序运行在一个模拟的 Linux 环境 MSYS2 中，它对文件路径的解析或对 Windows 系统 ssh-agent 密钥代理服务的读取存在偏差。这导致它在连接 GitHub 时交不出密钥，从而被服务端拒绝。&lt;/p&gt;
&lt;h2 id=&#34;四解决方案&#34;&gt;四、解决方案
&lt;/h2&gt;&lt;p&gt;明确了问题是环境割裂导致的，修复逻辑就是统一底层调用。我们需要通过 Git 的全局配置，覆写它的默认行为，强制 Git 放弃内部自带的 SSH，转而调用 Windows 系统的原生 SSH 程序。&lt;/p&gt;
&lt;p&gt;在终端执行以下配置命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git config --global core.sshCommand &lt;span class=&#34;s2&#34;&gt;&amp;#34;C:/Windows/System32/OpenSSH/ssh.exe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行完毕后，Git 的网络操作与系统的 ssh 命令彻底打通，底层调用的都是同一个能正确找到密钥的程序。再次执行 &lt;code&gt;git clone&lt;/code&gt; 即可顺利拉取代码。&lt;/p&gt;
&lt;h2 id=&#34;五总结&#34;&gt;五、总结
&lt;/h2&gt;&lt;p&gt;在开发环境搭建中，多套工具链附带的同名依赖组件往往是引发底层冲突的根源。遇到配置生效不一致的情况，利用 &lt;code&gt;GIT_SSH_COMMAND=&amp;quot;ssh -v&amp;quot;&lt;/code&gt; 这类环境变量暴露出底层的真实调用路径，是打破信息差、快速定位问题的有效手段。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Node/npm/pnpm 安装指南</title>
        <link>https://jiangwan.ink/p/node-npm-pnpm-install-guide/</link>
        <pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate>
        
        <guid>https://jiangwan.ink/p/node-npm-pnpm-install-guide/</guid>
        <description>&lt;h2 id=&#34;一引言&#34;&gt;一、引言
&lt;/h2&gt;&lt;p&gt;在动手安装之前，我们先理清一个概念：&lt;strong&gt;Node.js 是一个 JavaScript 运行环境&lt;/strong&gt;。当你安装 Node.js 时，它会“买一赠一”地在你的系统里捆绑安装官方的包管理器，&lt;strong&gt;npm (Node Package Manager)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;既然官方自带了 npm，为什么大家还要折腾？答案很简单：天下苦 &lt;code&gt;node_modules&lt;/code&gt; 久矣。&lt;/p&gt;
&lt;h3 id=&#34;1-npm-的痛点曾经的依赖黑洞&#34;&gt;1. npm 的痛点：曾经的“依赖黑洞”
&lt;/h3&gt;&lt;p&gt;早期的 npm 有几个让开发者头疼的缺陷：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;极其占空间&lt;/strong&gt;：每个项目都会在根目录下生成一个独立的 &lt;code&gt;node_modules&lt;/code&gt; 文件夹。如果你有 10 个项目都用到了同一个库（比如 React），这个库就会在你的硬盘里被重复下载、完整保存 10 次。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;速度慢&lt;/strong&gt;：串行安装机制导致下载速度令人抓狂。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-pnpm-的破局硬盘空间魔法&#34;&gt;2. pnpm 的破局：硬盘空间魔法
&lt;/h3&gt;&lt;p&gt;pnpm（Performant npm）是目前开源社区最推荐的包管理器之一，它直接解决了上述痛点。&lt;/p&gt;
&lt;p&gt;它巧妙地使用了计算机文件系统中的 &lt;strong&gt;硬链接（Hard link）&lt;/strong&gt; 技术。无论你在电脑上创建了多少个项目，只要它们用到了同一个版本的某个包，&lt;strong&gt;pnpm 只会在系统全局的 Store 中保存一份实体文件&lt;/strong&gt;，然后通过硬链接将它们映射到各个项目的 &lt;code&gt;node_modules&lt;/code&gt; 中。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;：极速的安装时间 + 极大地节省硬盘空间 = &lt;strong&gt;无脑选 pnpm&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;二实战演练&#34;&gt;二、实战演练
&lt;/h2&gt;&lt;p&gt;如果你只是单纯地为了跑脚手架、装依赖，直接去官网下载安装包绝对是最省事的选择。&lt;/p&gt;
&lt;h3 id=&#34;步骤一官网直装-nodejs&#34;&gt;步骤一：官网直装 Node.js
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;打开 &lt;a class=&#34;link&#34; href=&#34;https://nodejs.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Node.js 官方网站&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;强烈建议下载 LTS（长期维护版）&lt;/strong&gt;，不要去碰 Current（最新尝鲜版），能避免很多莫名其妙的兼容性报错。&lt;/li&gt;
&lt;li&gt;下载对应的 &lt;code&gt;.msi&lt;/code&gt; (Windows) 或 &lt;code&gt;.pkg&lt;/code&gt; (macOS) 文件，双击运行，一路点击 Next 完成安装。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;安装完成后，打开终端（CMD/PowerShell/Terminal），验证是否成功：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 验证 Node.js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;node -v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 验证赠送的 npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm -v
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;步骤二拯救-c-盘修改-npm-全局路径&#34;&gt;步骤二：拯救 C 盘（修改 npm 全局路径）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;这是无数 Windows 开发者痛彻心扉的踩坑点。&lt;/strong&gt; Node 本身装在 C 盘没关系，但 npm 默认会把以后所有全局安装的包和缓存文件都塞进 C 盘的 &lt;code&gt;AppData\Roaming&lt;/code&gt; 目录下。时间一长，C 盘直接标红。&lt;/p&gt;
&lt;p&gt;我们需要把这部分转移到 D 盘（或其他非系统盘）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 D 盘的 Node.js 安装目录下（或者你自定义的一个目录，比如 &lt;code&gt;D:\nodejs&lt;/code&gt;），新建两个文件夹：&lt;code&gt;node_global&lt;/code&gt; 和 &lt;code&gt;node_cache&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;打开终端，执行以下命令重定向路径：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 设置全局模块的安装路径&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; prefix &lt;span class=&#34;s2&#34;&gt;&amp;#34;D:\nodejs\node_global&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 设置缓存路径&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; cache &lt;span class=&#34;s2&#34;&gt;&amp;#34;D:\nodejs\node_cache&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;致命踩坑点：配置环境变量&lt;/strong&gt;。因为我们修改了全局安装路径，系统现在找不到你以后全局安装的命令了。你必须告诉 Windows 去哪里找：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;右键“此电脑” -&amp;gt; 属性 -&amp;gt; 高级系统设置 -&amp;gt; 环境变量。&lt;/li&gt;
&lt;li&gt;在“系统变量”中找到 &lt;code&gt;Path&lt;/code&gt;，双击编辑。&lt;/li&gt;
&lt;li&gt;新建一条，填入你刚才创建的全局路径：&lt;code&gt;D:\nodejs\node_global&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;一路点击“确定”保存，然后&lt;strong&gt;必须重启你的终端&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;步骤三配置镜像源与激活-pnpm&#34;&gt;步骤三：配置镜像源与激活 pnpm
&lt;/h3&gt;&lt;p&gt;网络问题是国内开发者的共同阻碍，我们需要把 npm 的下载源切换到国内镜像：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 设置淘宝镜像源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; registry https://registry.npmmirror.com/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后，利用刚刚配置好的 npm，全局安装并激活 pnpm：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 全局安装 pnpm（它现在会被安装到 D:\nodejs\node_global 里）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g pnpm
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 为 pnpm 同样配置国内镜像源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; registry https://registry.npmmirror.com/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 验证安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm -v
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;至此，你的电脑不仅拥有了一个干净、极速、省空间的 pnpm 环境，还成功保卫了你宝贵的 C 盘容量。以后遇到任何项目的 &lt;code&gt;npm install&lt;/code&gt; 指令，都可以愉快地替换成 &lt;code&gt;pnpm install&lt;/code&gt; 了。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
