Although this works, I'm not entirely sure why the -f
option is needed:
ssh-copy-id -f -o IdentityFile=~/.ssh/old/id_rsa -i ~/.ssh/id_rsa me@example.com
Trying to run the same command without the -f option results in:
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
But this is 100% untrue, as ~/.ssh/id_rsa.pub was freshly generated, and sure enough, listing the keys stored in ~/.ssh/authorized_keys on the server before (and after) running the command only showed the key stored in ~/.ssh/old/id_rsa.pub.
Subsequently running the command including the -f option correctly results in ~/.ssh/id_rsa.pub being added to ~/.ssh/authorized_keys on the server, with no duplication of any sort.
Either I'm missing something (likely) or this is a bug, I'm not sure which one is it.
Another way:
ssh-copy-id -i ~/.ssh/id_rsa me@example.com
Or, if the old key is not loaded into the SSH agent anymore (and you can't / don't want to use password authentication to push the new key):
ssh-add ~/.ssh/old/id_rsa/ && ssh-copy-id -i ~/.ssh/id_rsa me@example.com && ssh-add -d ~/.ssh/old/id_rsa/ me@example.com
Which will load the old key into the SSH agent before attempting to push the new key, and remove the key from SSH the agent right after the new key has been pushed.
Addressing why your command didn't work:
From man ssh-copy-id:
SYNOPSIS
ssh-copy-id [-f] [-n] [-s] [-x] [-i [identity_file]] [-p port]
[-o ssh_option] [-t target_path] [user@]hostname
ssh-copy-id -h | -?
Which highlights the main issue with your command: -i and [user@]hostname are positional, i.e. you must pass -i before [user@]hostname.
Additionally your attempt:
ssh-copy-id "me@example.com -i ~/.ssh/old/id_rsa"
is quoting the destination and the identity file as a single string; this prevents them from being recognized as separate options, and me@example.com -i ~/.ssh/old/id_rsa are being interpreted as a single argument, leading to the error you experienced:
/usr/bin/ssh-copy-id: ERROR: ssh: Could not resolve hostname example.com -i ~/.ssh/old/id_rsa: Name or service not known
(not to mention the double quotes would have prevented ~ from expanding anyways).
All you need to do is to unquote what you have and switch the order of the arguments:
ssh-copy-id -i ~/.ssh/id_rsa me@example.com