如何为 git 指定 ssh 密钥文件
On 2014-04-20 13:18:18 By Soli如何为 git 指定 ssh 密钥文件
如果你在运行 ssh 命令时想指定一个密钥文件,一种很简便的方法就是使用 -i
选项。
ssh -i ~/.ssh/thatuserkey.pem [email protected]
这样非常干净利索。既简单、优雅,又十分直观。对 git 命令,我也想这么做:
git -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git
然而,git 命令并没有这样的 -i
选项。真糟糕!
我找了很久都没找到类似的解决办法。我只能想到如下两种备选方案:
- 使用 GIT_SSH 环境变量
- 使用包裹脚本(wrapper script)
备选1:使用 GIT_SSH 环境变量
此方案中,你可以这样来为 git 命令指定一个密钥文件:
PKEY=~/.ssh/thatuserkey.pem git clone [email protected]:/git/repo.git
其中,~/.ssh/thatuserkey.pem
就是你想使用的密钥文件。
为了能让这正常运行,还需要进行一些预配置。首先,要创建包含如下内容的脚本 ~/ssh-git.sh
:
#!/bin/sh
if [ -z "$PKEY" ]; then
# if PKEY is not specified, run ssh using default keyfile
ssh "$@"
else
ssh -i "$PKEY" "$@"
fi
这个脚本必须是可执行的,所以需要对它执行 chmod +x
。
接下来,需要把 GIT_SSH 的值设置为指向上述脚本的路径。并且这个变量需要导出到 shell 环境。
export GIT_SSH=~/ssh-git.sh
现在,你每次运行 git 命令时,用 PKEY 指定的密钥文件就会传递给用 GIT_SSH 指定的脚本。这就会让 git 命令使用该密钥文件进行连接。
PKEY=~/.ssh/thatuserkey.pem git clone [email protected]:/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
如果你也这么认为,那这里还有另一个备选项。
备选2:使用包裹脚本
git 命令的 -i
选项非常工整且优雅。你可以用 -i
选项来提供你想要使用的密钥文件。如果你没用这个选项,ssh 就会转而用默认的密钥文件。
如果要对 git 命令也是用 -i
选项,你就需要写个包裹脚本。包裹脚本可以让我们以我们想要的方式来设置用法,也就是模拟 ssh 的 -i
选项。
用法应该差不多像这样:
git.sh -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git
其中的 git.sh 就是我们的包裹脚本。
你只需要创建这个脚本,然后把它放到你的 PATH 路径下就搞定了。
你可以直接在这里下载或直接拷贝下面的代码:
#!/bin/bash
# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
if [ $# -eq 0 ]; then
echo "Git wrapper script that can specify an ssh-key file
Usage:
git.sh -i ssh-key-file git-command
"
exit 1
fi
# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0
if [ "$1" = "-i" ]; then
SSH_KEY=$2; shift; shift
echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
chmod +x /tmp/.git_ssh.$$
export GIT_SSH=/tmp/.git_ssh.$$
fi
# in case the git command is repeated
[ "$1" = "git" ] && shift
# Run the git command
git "$@"
这个脚本会优雅的处理失败的情况。如果你没指定 -i
选项,它会使用默认密钥文件来运行 git 。
这个包裹脚本使用了与 GIT_SSH 相同的原理。但与手动预配置不同的是,这个包裹脚本会在每次运行真正的 git 命令之前,临时把所有这些设置好。
其他备选项
还有其他方法可以让 git 命令使用不同的密钥文件。那就是使用 $HOME/.ssh/config
文件来为你想要连接的不同的主机映射不同的密钥文件(译者注:请参考这里)。但这种方法不能让你在运行 git 命令时任意的选择密钥文件。那些密钥文件必须得提前在配置文件中定义好才行。
你还可以用 ssh-agent 来把你想用的密钥文件加进去。我还写了一个基于 ssh-agent 的支持 -i
选项的包裹脚本。事实证明,它比 GIT_SSH 的方式还复杂。我可能还会写篇博客来展示一下那种方式是怎么搞的。
在所有这些不同的方法中,并没有哪种更好。这完全要看你使用的环境和你的个人喜好。
Alvin
注:本文翻译自 How to specify an ssh-key file with the Git command
相关文章:如何向 git 传递 ssh 选项