Command-line access to OS X's keychain - How to get e-mail address associated with account

3

I'm writing a Bash command-line tool that accesses the keychain for emulating a web browser to communicate with web pages.

It's quite straightforward to get the password stored in the keychain from there:

PASSWORD=`security find-internet-password -gs accounts.google.com -w`

But it's a bit more tricky to extract the email address, as the most specific command you get for this returns a lot of information:

$security find-internet-password -gs accounts.google.com
/Users/me/Library/Keychains/login.keychain"
class: "inet"
attributes:
    0x00000007 <blob>="accounts.google.com"
    0x00000008 <blob>=<NULL>
    "acct"<blob>="my-email-address@gmail.com"
    "atyp"<blob>="form"
    "cdat"<timedate>=0x32303135303333303134333533315A00  "20150330143531Z\000"
    "crtr"<uint32>="rimZ"
    "cusi"<sint32>=<NULL>
    "desc"<blob>=<NULL>
    "icmt"<blob>=<NULL>
    "invi"<sint32>=<NULL>
    "mdat"<timedate>=0x32303135303333303134333533315A00  "20150330143531Z\000"
    "nega"<sint32>=<NULL>
    "path"<blob>="/ServiceLogin"
    "port"<uint32>=0x00000000 
    "prot"<blob>=<NULL>
    "ptcl"<uint32>="htps"
    "scrp"<sint32>=<NULL>
    "sdmn"<blob>=<NULL>
    "srvr"<blob>="accounts.google.com"
    "type"<uint32>=<NULL>
password: "my-password"

How would you extract the account e-mail address from the line starting with "acct"<blob>= and store it, say, to a variable called EMAIL?

macos
bash
keychain
asked on Stack Overflow Apr 9, 2015 by Pierre F • edited Apr 9, 2015 by Michael Jaros

2 Answers

1

If you're using multiple grep, cut, sed, and awk statements, you can usually replace them with a single awk.

PASSWORD=$(security find-internet-password -gs accounts.google.com -w)
EMAIL=$(awk -F\" '/acct"<blob>/ {print $4}'<<<$PASSWORD)

This may be easier on a single line, but I couldn't get the security command to print out an output like yours in order to test it. Plus, it's a bit long to show on StackOverflow:

EMAIL=$(security find-internet-password -gs accounts.google.com -w | awk -F\" '/acct"<blob>/ {print $4}')

The /acct"<blob>/ is a regular expression. This particular awk command line will filter out lines that match this regular expression. The -F\" divides the output by the field given. In your line, the fields become:

  • The spaces in the front of the line.
  • acct
  • <blob>
  • my-email-address@gmail.com
  • A null field

The {print $4} says to print out the fourth field.

By the way, it's usually better to use $(....) instead of back ticks in your Shell scripts. The $( ... ) are easier to see, and you can enclose subcommands to execute before your main command:

foo=$(ls $(find . -name "*.txt"))
answered on Stack Overflow Apr 9, 2015 by David W.
0
EMAIL=`security find-internet-password -s accounts.google.com | grep acct | cut -d "=" -f 2`
EMAIL="${EMAIL:1:${#EMAIL}-2}" # remove the brackets

Explanation:

  • grep acct keeps only the line containing the string "acct"
  • cut -d "=" -f 2 parses that line based on the separator "=" and keeps the 2nd part, i.e. the part after the "=" sign, which is the e-mail address enclosed within brackets
  • EMAIL="${EMAIL:1:${#EMAIL}-2}" removes the first and last characters of that string, leaving us with the clean e-mail address we were looking for
answered on Stack Overflow Apr 9, 2015 by Pierre F • edited Apr 12, 2015 by Community

User contributions licensed under CC BY-SA 3.0