如何为 Git 指定 SSH 密钥文件
如果你只希望对单个 git server 配置独立的 ssh key,可以在 ~/.ssh/config
里面加上如下配置即可:
1 | Host github.com |
以下内容为转载:
如果你在运行 ssh 命令时想指定一个密钥文件,一种很简便的方法就是使用 -i 选项。
ssh -i ~/.ssh/thatuserkey.pem thatuser@myserver.com
这样非常干净利索。既简单、优雅,又十分直观。对 git 命令,我也想这么做:
git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
然而,git 命令并没有这样的 -i 选项。真糟糕!
我找了很久都没找到类似的解决办法。我只能想到如下两种备选方案:
- 使用 GIT_SSH 环境变量
- 使用包裹脚本(wrapper script)
使用 GIT_SSH 环境变量
此方案中,你可以这样来为 git 命令指定一个密钥文件:
PKEY=~/.ssh/thatuserkey.pem git clone thatuser@myserver.com:/git/repo.git
其中,~/.ssh/thatuserkey.pem
就是你想使用的密钥文件。
为了能让这正常运行,还需要进行一些预配置。首先,要创建包含如下内容的脚本 ~/ssh-git.sh:
1 |
|
这个脚本必须是可执行的,所以需要对它执行 chmod +x 。
接下来,需要把 GIT_SSH 的值设置为指向上述脚本的路径。并且这个变量需要导出到 shell 环境。
export GIT_SSH=~/ssh-git.sh
现在,你每次运行 git 命令时,用 PKEY 指定的密钥文件就会传递给用 GIT_SSH 指定的脚本。这就会让 git 命令使用该密钥文件进行连接。
PKEY=~/.ssh/thatuserkey.pem git clone thatuser@myserver.com:/git/repo.git
从此,每次运行 git 命令时,只需设置 PKEY 变量,你就可以随意使用你想要的密钥文件。 [1]
如果你在运行 git 命令时未设置 PKEY , GIT_SSH 脚本仍然会被执行,因为它已经被导出到 shell 环境中了。但脚本会自动判断,如果没有设置 PKEY 就不会使用 -i 选项,这样 git 仍然会使用默认密钥文件运行。
在把 PKEY 导出到 shell 环境中时需要谨慎一些,因为无论它被设置成什么值,GIT_SSH 脚本都会使用它,即使你并没有在 git 命令里指定它。把 GIT_SSH 导出到 shell 环境中会带来另一个问题,就是 git 在运行时总会使用它。因此你需要时刻提醒自己你设置了它。你可以在每次运行 git 命令时设置 GIT_SSH 以防止它被导出到 shell 环境,代价就是整个命令将会更长。
设置 PKEY 的用法虽然可行,但在 git 命令中设置 PKEY 总觉得不那么常规。[2]
如果你也这么认为,那这里还有另一个备选项。
使用包裹脚本
git 命令的 -i 选项非常工整且优雅。你可以用 -i 选项来提供你想要使用的密钥文件。如果你没用这个选项,ssh 就会转而用默认的密钥文件。
如果要对 git 命令也是用 -i 选项,你就需要写个包裹脚本。包裹脚本可以让我们以我们想要的方式来设置用法,也就是模拟 ssh 的 -i 选项。
用法应该差不多像这样:
git.sh -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git
其中的 git.sh 就是我们的包裹脚本。
你只需要创建这个脚本,然后把它放到你的 PATH 路径下就搞定了。
你可以直接在这里下载或直接拷贝下面的代码:
1 |
|
这个脚本会优雅的处理失败的情况。如果你没指定 -i 选项,它会使用默认密钥文件来运行 git 。
这个包裹脚本使用了与 GIT_SSH 相同的原理。但与手动预配置不同的是,这个包裹脚本会在每次运行真正的 git 命令之前,临时把所有这些设置好。
其他备选项
还有其他方法可以让 git 命令使用不同的密钥文件。那就是使用 $HOME/.ssh/config
文件来为你想要连接的不同的主机映射不同的密钥文件(译者注:请参考这里)。但这种方法不能让你在运行 git 命令时任意的选择密钥文件。那些密钥文件必须得提前在配置文件中定义好才行。
你还可以用 ssh-agent 来把你想用的密钥文件加进去。我还写了一个基于 ssh-agent 的支持 -i 选项的包裹脚本。事实证明,它比 GIT_SSH 的方式还复杂。我可能还会写篇博客来展示一下那种方式是怎么搞的。
在所有这些不同的方法中,并没有哪种更好。这完全要看你使用的环境和你的个人喜好。