DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Load OS X's Environment.plist In Your Shell

08.19.2005
| 14130 views |
  • submit to reddit
        To make environment variables available to Mac OS X GUI applications, those variables must be defined in your ~/.MacOSX/environment.plist. Sometimes you want to have those same environment variables available from your shell as well. If you're using Terminal, that's no problem--the variables from environment.plist are available. But what if you need to SSH into the machine? 

Adhering to the DRY principle, this script can be launched from your shell's rc file to load up the environment variables from environment.plist. To load it into my tcsh environment, I use

if ($?SSH_CLIENT) then
    eval `~/bin/parseEnvironmentPlist.rb`
endif

And here's the ruby script:

#!/usr/bin/ruby

#
# A script for parsing ~/.MacOSX/environment.plist and loading the 
# environment variables it defines into a shell environment.
#

# determine which shell the user is running
# currently we support bash and tcsh
if /^\/[-A-Za-z\/]+\/(bash|tcsh)$/ =~ ENV['SHELL']
    shell = $1
else
    # if we can't determine the users shell, or if
    # it's an unsupported shell, bail out here
    exit 1
end

# a regex for matching <key>...</key> lines
# group 1 is the name of the key
key_re = /^\s*<key>([A-Za-z]+[_A-Za-z0-9]*)<\/key>\s*$/

# a regex for matching <string>...</string> value lines
# group 1 is the value of the environment variable
value_re = /^\s*<string>([-_:.\/0-9A-Za-z]+)<\/string>\s*$/

File.open("#{ENV['HOME']}/.MacOSX/environment.plist", "r") do |plist|

    currentKey = "" # the key we're currently processing
    
    # look at each line of the file to find keys
    # followed by values
    plist.each_line do |next_line| 
    
        # if we find a key, hold on to it 
        if key_re =~ next_line
            currentKey = $1
            currentValue = ""
        
        # since key lines alternate with value lines,
        # if we match a value line, we know it's a value
        # for the previously matched key
        elsif value_re =~ next_line
            currentValue = $1
        
            if shell == "bash"
                # output a setenv command to stdout that's 
                # suitable for running through bash's eval
                puts "#{currentKey}=#{currentValue}; export #{currentKey};"
            elsif shell == "tcsh"
                # output a setenv command to stdout that's 
                # suitable for running through tcsh's eval
                puts "setenv #{currentKey} #{currentValue};"
            else
                # we should never get to this point since we 
                # exit much earlier if the shell type can't be 
                # determined. But, just in case, exit here too.
                exit 1
            end
        
            currentKey = currentValue = ""
        end
    
    end

end

I wrote this script back when I was first learning Ruby, so A) that's why there are so many comments and 2) it could probably be improved, but it works for me!    

Comments

Snippets Manager replied on Wed, 2010/06/23 - 4:59am

You should use "defaults" to operate on .plist files. To export all variables defined in $HOME/.MacOSX/environment, use: for i in `defaults read $HOME/.MacOSX/environment \ | sed -nE 's/^ ([a-zA-Z0-9]+) = (.+");/\1/p'`; do eval export $i="`defaults read $HOME/.MacOSX/environment $i`" done