Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Hello I am looking for assistance searching /root/.ssh/authorized_keys for a given public key (call it $pub_key) and removing it. Want to do this in bash script.

What's the best way to accomplish this?

share|improve this question
up vote 8 down vote accepted

Would grep -v $pub_key /root/.ssh/authorized_keys > /tmp/ work? You can compared to two files to verify the work. Given the long strings of random characters that comprise the keys, it's probably sufficient to do this using a substring of $pub_key.

share|improve this answer
Actually, that just cleared out the entire file, it didn't just remove the passed in $pub_key – Justin Sep 8 '11 at 23:27
I think I need to use sed, but can't figure out the syntax, here is what I have thus far: sed -i '/$pub_key/ d' /root/.ssh/authorized_keys – Justin Sep 8 '11 at 23:36
Seriously, the grep didn't work? Try a substring. Something like "grep -v CqcQ9rbUrPBczdoHBAe72Z /root/.ssh/authorized_keys". There's so much entropy in these keys that any reasonably sized substring won't be repeated in any other key. You don't need to need the whole 500+ character key. The syntax on the sed is correct, though I would be nervous about using the "-i" option; make backups if you use it. – cjc Sep 9 '11 at 0:10

I think I need to use sed, but can't figure out the syntax, here is what I have thus far:

sed -i '/$pub_key/ d' /root/.ssh/authorized_keys

Remove the space before d, it will work as you expect:

sed -i '/$pub_key/d' /root/.ssh/authorized_keys
share|improve this answer
My keys have a half-dozen slash characters in them that would need to be escaped. I would use '\|$pub_key|d' to get sed to use | as an alternate delimiter rather than adding backslashes to $pub_key – DerfK Sep 9 '11 at 3:12
Hmm. If you insist on using $pub_key for the whole key, do something this: "$substring = echo $pub_key | cut -c30-60 ; mv authorized_keys authorized_keys.bak ; grep -v $substring authorized_keys.bak > authorized_keys". grep doesn't care about the delimiters. When it didn't work before, you probably expressed $pub_key as the whole thing, but there are spaces in there. In that case, you should have mentioned the error, and I would have suggested enclosing $pub_key in quotes. – cjc Sep 9 '11 at 9:59

Never forget the power of perl oneliners!

$pub_key="AAAABCD"; perl -i "/$pub_key/ or print" /root/.ssh/authorized_keys

That will perform an in-place edit and remove the offending key.

Or, perhaps you have a really really long authorized_keys file and you want to process it in parallel with gnu parallel?

pub_key="AAAABCD"; parallel -k "echo {} | grep -v $pub_key" </root/.ssh/authorized_keys

the possibilities are endless.

update: fixed typo that Ole pointed out. Thanks Ole!

share|improve this answer
Remove the first $ to set the variable. Apart from that you should consider using --pipe if your authorized_keys is of the size where it will benefit from parallel processing. – Ole Tange Sep 9 '11 at 11:36
Ole is there a way to do 'edit in place' with parallel as above? – Phil Hollenback Sep 9 '11 at 17:23

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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