修复 Git 无法连接 Pageant 的问题

现象

预期在 Windows 11 当前账号 .ssh\config 配置 ssh 配置后,使用 Git 免 ssh 证书密码登录

在 PowerShell 中执行以下命令

1
tasklist | findstr pageant 

示例

1
2
3
PS C:\Users\nobody> tasklist | findstr pageant        
pageant.exe 4900 Console 1 61,652 K
ssh-pageant.exe 1588 Console 1 8,772 K

如果出现 ssh-pageant 进程 ID 大于 pageant ID 的情况,则表明 ssh-pageant 与 pageant 无法正常通信

解决方案

在 PowerShell 中执行以下命令

1
notepad $PROFILE

粘贴一下代码,并保存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 解决 Windows 11 使用 ssh 命令,无法使用 pageant 加载好的密钥
# 检查 Pageant 是否正在运行
$pageantProcess = Get-Process pageant -ErrorAction SilentlyContinue

if ($pageantProcess) {
Write-Host "Pageant is running, setting up SSH agent..." -ForegroundColor Yellow

# 尝试多个可能的 ssh-pageant 位置
$possiblePaths = @(
"ssh-pageant", # 如果在 PATH 中
"$HOME\.ssh\tools\ssh-pageant.exe",
"$env:ProgramFiles\Git\usr\bin\ssh-pageant.exe",
"${env:ProgramFiles(x86)}\Git\usr\bin\ssh-pageant.exe",
"C:\tools\ssh-pageant\ssh-pageant.exe"
)

$sshPageantPath = $null
foreach ($path in $possiblePaths) {
if (Get-Command $path -ErrorAction SilentlyContinue) {
$sshPageantPath = (Get-Command $path).Source
break
}
}

if ($sshPageantPath) {
Write-Host "Found ssh-pageant at: $sshPageantPath" -ForegroundColor Blue

$homeSocketPath = "$HOME\.ssh\pageant.socket"

function callConnetSSH {
# 确保 socket 目录存在
$socketDir = Split-Path -Path $homeSocketPath -Parent
if (!(Test-Path $socketDir)) {
New-Item -ItemType Directory -Path $socketDir -Force | Out-Null
}

# 使用更可靠的方法获取输出
$output = & $sshPageantPath -r -a $homeSocketPath 2>&1

if ($LASTEXITCODE -eq 0) {
# 尝试不同的输出解析方法
$socketPath = $null

# 方法1: 正则匹配
if ($output -match "SSH_AUTH_SOCK='([^']+)'") {
$socketPath = $matches[1]
}
# 方法2: 直接使用 socket 文件路径
elseif (Test-Path $homeSocketPath) {
$socketPath = $homeSocketPath
}
# 方法3: 使用标准路径
else {
$socketPath = $homeSocketPath
}

if ($socketPath) {
$env:SSH_AUTH_SOCK = $socketPath
Write-Host "✓ SSH agent socket set to: $socketPath" -ForegroundColor Green

# 验证设置是否成功
if (Test-Path $env:SSH_AUTH_SOCK) {
Write-Host "✓ SSH agent socket verified" -ForegroundColor Green
}
} else {
Write-Warning "Could not determine SSH agent socket path"
}
} else {
if("ssh-pageant: connect: Bad file descriptor" -eq $output) {
# Write-Warning "Please Pestat Terminal.$homeSocketPath"
Write-Warning "Clean.Call Again"
Remove-Item -Path $homeSocketPath -Force
callConnetSSH
} else {
Write-Warning "ssh-pageant exited with error code: $LASTEXITCODE"
Write-Warning "Output: $output"
}
}
}


try {
callConnetSSH
} catch {
if ("Cannot index into a null array." -eq $_) {
Write-Warning "Call Again"
callConnetSSH
} else {
Write-Warning "Failed to run ssh-pageant: $_"
}
}
} else {
Write-Warning "ssh-pageant not found. Please install it or use Windows OpenSSH agent."
Write-Host "Alternative: Run 'Start-Service ssh-agent' and 'ssh-add ~\.ssh\id_rsa'" -ForegroundColor Cyan
}
} else {
# Write-Warning "Pageant is not running. Start Pageant first or use Windows SSH agent."
}

关闭所有的 PowerShell 或 命令窗口

验证

1
ssh -T git@example.com
1
2
PS C:\Users\nobody>ssh -T git@example.com
Welcome to GitLab, @gitUser!

如果还有其他问题,可以使用 ssh 调试命令,再分析其他原因

1
ssh -vvvT git@example.com