Reputation: 1392
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>="[email protected]"
"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
?
Upvotes: 3
Views: 2918
Reputation: 1392
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 bracketsEMAIL="${EMAIL:1:${#EMAIL}-2}"
removes the first and last characters of that string, leaving us with the clean e-mail address we were looking forUpvotes: 0
Reputation: 107040
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:
acct
<blob>
[email protected]
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"))
Upvotes: 1