For reasons too annoying to explain, my GnuPG keyring was huge. It was taking a long time to find keys, and most of them weren’t ones I’d use. So I wrote this little script that strips out all of the keys that aren’t
- yours, or
- signatories to your key.
The script doesn’t actually delete any keys. It produces shell-compatible output that you can pipe or copy to a shell. Now my keyring file is less than 4% the size (or more precisely, 37‰) of the size it was before.
#!/bin/bash # clean_keyring.sh - clean up all the excess keys # my key should probably be the first secret key listed mykey=$(gpg --list-secret-keys | grep '^sec' | cut -c 13-20 | head -1) if [ -z $mykey ] then # exit if no key string echo "Can't get user's key ID" exit 1 fi # all of the people who have signed my key mysigners=$(gpg --list-sigs $mykey | grep '^sig' | cut -c 14-21 | sort -u) # keep all of the signers, plus my key (if I haven't self-signed) keepers=$(echo $mykey $mysigners | tr ' ' '\012' | sort -u) # the keepers list in egrep syntax: ^(key|key|…) keepers_egrep=$(echo $keepers | sed 's/^/^(/; s/$/)/; s/ /|/g;') # show all the keepers as a comment so this script's output is shell-able echo '# Keepers: ' $keepers # everyone who isn't on the keepers list is deleted deleters=$(gpg --list-keys | grep '^pub'| cut -c 13-20 | egrep -v ${keepers_egrep}) # echo the command if there are any to delete # command is interactive if [ -z $deleters ] then echo "# Nothing to delete!" else echo 'gpg --delete-keys' $deleters fi
Files:
- clean_keyring.sh (SHA-1 checksum: 8c71dabca84c33201184fe348ae35310622d2be6)
- clean_keyring.sh.txt — gpg signature.
Nice script – just what I needed just now.
Unfortunately it has a few flaws for my use – shared here in case it is useful for others:
the -z tests take a single argument, so variable needs to be quoted (it can expand to nothing or multiple arguments).
gpg should use –with-colons option in scripts (breaks e.g. with gpg2 and non-US locales), and key can then be had piping through “cut -d: -f5”
gpg should use –batch option in scripts. Particularly the last one, which (if you dare) could also use –yes option to be fully automated.
There’s no benefit in grabbing only first key with secret key: gpg fails if told to remove a key that has a corresponding secret key. Better is to simply treat _all_ keys with secret key as “mine”.
Thanks for the tips. It was definitely an ad hoc script that worked for me. As with everything on the web, use at your own risk.
Great script but in my case I have an old secret key revoked that appears before than current secret key.
But it been easy to solve adding a “grep -v expires” before “grep ^sec” to get only the valid secret key.