Bash 脚本在输入密码短语后不生效

Bash script don't take efect ater passphrase enter

我不想自动登录到 ssh 代理,但只有效执行 'sh' 文件中的简单脚本:

#!/bin/bash
clear
echo " >> Start the ssh-agent in the background."
eval $(ssh-agent -s)
echo " >> Add SSH private key to the ssh-agent"
ssh-add ~/.ssh/id_rsa
echo " >> List of ssh agents"
ssh-add -l
echo " >> Attempts ssh to GitHub"
ssh -T git@github.com

它确实会触发密码请求并等待输入,即使不在主目录中。 git 通知 'Identity added:' 和“您已成功验证”

但问题是在尝试与 Github 通信后 - 'git push' 或 'pull' 命令没有任何积极效果:

sign_and_send_pubkey: signing failed: agent refused operation
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists. 

在那个问题之后,我可以从键盘输入相同的命令,例如

ssh-add ~/.ssh/id_rsa

输入密码,然后它使我能够与 Github 成功通信。上面的脚本有什么问题?

我的背景:

OS name: "linux", version: "4.15.0-76-generic", arch: "amd64", family: "unix"

ssh-agent 通过设置一堆环境变量来告诉您的 shell 如何与之通信。它将它们打印到 STDOUT 并 eval $(ssh-agent -s) 将它们转换为环境变量。重要的是 SSH_AUTH_SOCK 指向用于与代理通信的套接字文件。

$ echo $SSH_AUTH_SOCK
/tmp/path/to/the/socket

环境变量仅对当前进程及其子进程有效。您的 shell 程序在新进程中执行。 shell 程序中设置的任何环境变量都会随着 shell 程序一起消失。您的 shell 将不知道如何与代理交谈。

你有两个选择。

首先,您可以 source 它而不是执行您的 shell 程序。这会在您当前的 shell 中将其作为一系列 shell 命令运行,就像您输入它们一样。脚本设置的环境变量将保留。

其次,更好的方法是在您登录时启动 ssh-agent。有 many ways to do this depending on your operating system。您可能已经有一个 运行。检查 $SSH_AUTH_SOCK.


PS echo " >> List of ssh agents" 应该是 echo " >> List of ssh keys"

我用 Funtoo keychain 解决了这个问题。我在我的 .bash_profile 中调用了钥匙串,这样我第一次登录时,它会要求输入密码,但不是每次都这样。它可以选择在代理中要求某些密钥,并且仅在它们不存在时提示您。

这是我的相关行。bash_profile:

keychain --inherit any ~/.ssh/id_rsa_github
. ~/.keychain/$HOSTNAME-sh

--inherit any 选项告诉 keychain 继承任何已经存在的 ssh-agent(例如系统代理,或已经 运行 的代理,或 gnome-keyring 或你拥有的)。如果 none 存在,它将启动一个。然后 keychain 在我的主目录 (~/.keychain/$HOSTNAME-sh) 中写入一个 shell 脚本,我的 .bash_profile 来源(使用上面的 . 命令)。 keychain 的第二个参数(上面的 ~/.ssh/id_rsa_github)是需要加载的密钥。 keychain 第一次运行时,发现密钥不在代理中,因此提示用户输入密码。它运行的任何后续时间都会检测到密钥存在,并且不会提示用户。