In my day-to-day, I need to ssh to various machines, all of which I have a different private key for.

When I start a new shell session - only my default id_rsa is added to the ssh key chain - I have been running

ssh-add ~/.ssh/*

However this also trys to, and fails, when adding things like ~/.ssh/config

Using find / grep, how can I go about only adding valid private key files?

  • 2
    Is there a reason you need to add all these keys? If you specify the IdentityFile for each host inside your ~/.ssh/config file, ssh will use that file when you try to connect. – SauceCode Nov 9 '16 at 16:23
  • Using Amazon AWS, my host IP address are ephemeral, and are constantly changing ( test stacks ). I can not rely on a config file to always be correct. Each layer of the stack has different user permissions. – Matt Clark Nov 9 '16 at 16:30

Slightly convoluted, but:

for possiblekey in ${HOME}/.ssh/id_*; do
    if grep -q PRIVATE "$possiblekey"; then
        ssh-add "$possiblekey"

You can also add all of your keys to your ~/.ssh/config each in their own IdentityFile directive outside of a Host directive:

# Global SSH configurations here will be applied to all hosts
IdentityFile ~/.ssh/id_dsa
IdentityFile ~/.ssh/id_project1
IdentityFile ~/.ssh/id_someotherkey

Host somespecifichost.example.com
    IdentityFile ~/.ssh/id_specifichostonlykey

The latter, honestly-better, method has the added perk of not suddenly picking up a new key that you've added without you explicitly adding it to the "keyring" as it were.

  • 1
    ohhh, good call. I did not actually know that IdentifyFile definitions could exist outside of a Host. – Matt Clark Nov 9 '16 at 16:45
  • Unfortunately this can prevent you from connecting to a server if you have many keys, claiming Too many authentication failures as it tries each key one by one for all servers, and some disconnect after a certain number of incorrect keys are tried. – Malvineous Feb 15 at 7:54

I have come up with the following command to do this:

find ~/.ssh/ -type f -exec grep -l "PRIVATE" {} \; | xargs ssh-add &> /dev/null

This will find all files in the .ssh directory that contain PRIVATE, passing the name / path of the private key file to ssh-add.


You don't really need find, you can just use a recursive grep using the l flag to send only matching filenames:

grep -slR "PRIVATE" ~/.ssh/ | xargs ssh-add

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.