15

I want to put ssh-add /path/to/special_key at the top of a script. This works fine, but it always prompts for the passphrase. This is strange, and a little annoying, as it still asks for the passphrase even when ssh-add -l shows the key has already been added.

Is there a way to tell it: "add this key and ask the passphrase if not already been added, otherwise do nothing" ?

18

I don't see any options to ssh-add that help achieve your desired result, but it's pretty easy to work around this, given that you're concerned with one key in particular.

First, grab the fingerprint for your special_key:

ssh-keygen -lf /path/to/special_key  | awk '{print $2}'

Let's say this fingerprint looks like 6d:98:ed:8c:07:07:fe:57:bb:19:12:89:5a:c4:bf:25

Then, at the top of your script, use ssh-add -l to check whether that key is loaded, before prompting to add it:

ssh-add -l |grep -q 6d:98:ed:8c:07:07:fe:57:bb:19:12:89:5a:c4:bf:25 || ssh-add /path/to/special_key

You can fold all this together into one line if you wish:

ssh-add -l |grep -q `ssh-keygen -lf /path/to/special_key  | awk '{print $2}'` || ssh-add /path/to/special_key
  • The one-liner is working nicely, thanks! – Darren Cook Jun 1 '14 at 2:09
  • 1
    I find this simplified one-liner to be a bit more comprehensible, and preferable since it avoids ssh-keygen (after all, I don't want to generate any keys), instead using the key path: ssh-add -l | grep -q 'path/to/key' || ssh-add /path/to/key – ohruunuruus Jan 17 '17 at 14:58
  • 1
    ssh-keygen in the answer does not generate a key - same as ssh-add -l in your example does not actually add anything. Flags modify the behaviour of the commands so it does not exactly match the name. Note that these versions functionally differ - if checking by path and the key at that path changes, your version would not pick it up. The version in the answer would also detect existing key no matter where it was loaded from. – Richlv May 15 at 11:18
5

There is no direct way to check using just ssh-add but you can make use of ssh-keygen and some scripting to check.

$ if  ssh-add -l | \
    grep -q "$(ssh-keygen -lf /path/to/special_key | awk '{print $2}')"; \
    then echo yes; \
    else echo no; \
  fi

The above would then print yes if the fingerprint represented by the file /path/to/special_key was present in ssh-add -l's output.

Example

$ if  ssh-add -l | \
    grep -q "$(ssh-keygen -lf /path/to/special_key | awk '{print $2}')"; \
    then echo yes; \
    else echo no; \
  fi
yes

Where the contents of output from ssh-keygen -lf /path/to/special_key looks like this:

$ ssh-keygen -lf /path/to/special_key
2048 8a:6a:5a:44:20:c8:3a:da:ab:dd:1c:12:2c:e4:20:0c  dev-servers (RSA)

And we're using `awk '{print $2}' to select just the 2nd column, which contains the fingerprint, i.e.:

8a:6a:5a:44:20:c8:3a:da:ab:dd:1c:12:2c:e4:20:0c

References

2

You might have particular reasons to be using ssh-add explicitly, but if you just want "I want to be prompted for my passphrase the first time I use the key, but not after that," openssh has a simpler solution:

Put AddKeysToAgent yes in your .ssh/config file.

  • Thanks. That was apparently added in ssh 7.2 (Ubuntu 18 appears to be on version 7.6). – Darren Cook Apr 29 at 16:43
  • Yup, "AddKeysToAgent isn't supported by my openssh version" is a good reason to use ssh-add explicitly ;-) – Nate Apr 29 at 23:52
0

ssh-add -K FILE worked fine for me on Mac.
It still shows "Identity added: " lines but doesn't ask for passphrase.

From man page:

-K When adding identities, each passphrase will also be stored in the user's keychain. When removing identities with -d, each passphrase will be removed from it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.