Load path

Hi,

I’ve discovered that the load path is different if I run sudo,
specifically it doesn’t pick up the value in GEM_HOME, even though sudo echo $GEM_HOME shows the correct path. Everything else I’ve checked
between sudo/not has been identical, so I was wondering where the load
path is originally set or when it’s first picked up?

I’m running ruby v1.9.2 on OSX 10.6. All the info below is identical,
except for the missing path in $: in sudo irb

echo $GEM_HOME
/Users/iainuser/.gems

sudo echo $GEM_HOME
/Users/iainuser/.gems

irb
puts $:
.
/Users/iainuser/.gems
/Users/iainuser/.gems/gems/wirble-0.1.3/bin
/Users/iainuser/.gems/gems/wirble-0.1.3/lib
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.4.0
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin10.4.0
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/1.9.1/x86_64-darwin10.4.0

sudo irb
puts $:
.
/Users/iainuser/.gems/gems/wirble-0.1.3/bin
/Users/iainuser/.gems/gems/wirble-0.1.3/lib
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.4.0
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin10.4.0
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/vendor_ruby
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/1.9.1
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/1.9.1/x86_64-darwin10.4.0

gem env
RubyGems Environment:

  • RUBYGEMS VERSION: 1.3.7
  • RUBY VERSION: 1.9.2 (2010-08-18 patchlevel 0) [x86_64-darwin10.4.0]
  • INSTALLATION DIRECTORY: /Users/iainuser/.gems
  • RUBY EXECUTABLE:
    /Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/bin/ruby
  • EXECUTABLE DIRECTORY: /Users/iainuser/.gems/bin
  • RUBYGEMS PLATFORMS:
    • ruby
    • x86_64-darwin-10
  • GEM PATHS:
    • /Users/iainuser/.gems
    • /Users/iainuser/.gems/gems

sudo gem env
RubyGems Environment:

  • RUBYGEMS VERSION: 1.3.7
  • RUBY VERSION: 1.9.2 (2010-08-18 patchlevel 0) [x86_64-darwin10.4.0]
  • INSTALLATION DIRECTORY: /Users/iainuser/.gems
  • RUBY EXECUTABLE:
    /Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/bin/ruby
  • EXECUTABLE DIRECTORY: /Users/iainuser/.gems/bin
  • RUBYGEMS PLATFORMS:
    • ruby
    • x86_64-darwin-10
  • GEM PATHS:
    • /Users/iainuser/.gems
    • /Users/iainuser/.gems/gems

Any insight is much appreciated.

Regards,
Iain

Iain B. wrote:

I’ve discovered that the load path is different if I run sudo,
specifically it doesn’t pick up the value in GEM_HOME, even though sudo echo $GEM_HOME shows the correct path.

sudo clears the environment. When you type

sudo echo $GEM_HOME

then the whole command line is expanded by the shell (including
replacing $GEM_HOME by the contents of the environment variable) before
it is run, and hence sudo echo gets passed the already-expanded string.

Try these:

sh -c ‘echo $GEM_HOME’
sudo sh -c ‘echo $GEM_HOME’

to get the true picture.

However you can configure sudo to pass through certain environment
variables (see ‘man 5 sudoers’), or you can do

sudo env GEM_HOME=$GEM_HOME gem install foo

The same question was asked recently at
http://www.ruby-forum.com/topic/214260
so there may be some more pointers in there.

Regards,

Brian.

On Sep 1, 2010, at 20:41 , Iain B. wrote:

I’ve discovered that the load path is different if I run sudo, specifically it doesn’t pick up the value in GEM_HOME, even though sudo echo $GEM_HOME shows the correct path. Everything else I’ve checked between sudo/not has been identical, so I was wondering where the load path is originally set or when it’s first picked up?

I got your back:

http://blog.zenspider.com/2009/08/gem-path-rubygems-and-you.html

On Sep 2, 2010, at 17:35 , Iain B. wrote:

I tried that just before I mailed in and it didn’t work :frowning:
Works for me:

502 % grep -A1 ryand /etc/sudoers

Added by ryand:

Defaults env_keep += “GEM_PATH GEM_HOME”

You need to pay attention to where you put that. It HAS to be after the
reset_env line or it obviously won’t work.

Last login: Thu Sep 2 18:34:01 on ttys002
501 % env | grep GEM
GEM_PATH=/Library/Ruby/Gems/1.8
502 % sudo bash
501 % env | grep GEM
GEM_PATH=/Library/Ruby/Gems/1.8

btw… are you sure you’ve exported your env vars?

Is there somewhere I can just add the path hardcoded? I don’t really care about configurability, I’m not moving my gems anywhere else soon.

Fix it correctly or don’t fix it at all. Anything else is just a
headache delayed.

Thanks for the responses.

On 2 Sep 2010, at 10:33, Ryan D. wrote:

I got your back:

http://blog.zenspider.com/2009/08/gem-path-rubygems-and-you.html

I tried that just before I mailed in and it didn’t work :frowning:

Try these:

sh -c ‘echo $GEM_HOME’
sudo sh -c ‘echo $GEM_HOME’

to get the true picture.

That gave me the same results as before, unfortunately. I’m a bit
perplexed as the env variables are being passed through but the load
path isn’t updated and is still missing the one line I want.

I don’t seem to be able to find how the load path is built
automatically, only stuff on how I can alter it after the fact, which
won’t help me in the long term.

Is there somewhere I can just add the path hardcoded? I don’t really
care about configurability, I’m not moving my gems anywhere else soon.

Regards,
Iain

Iain B. wrote:

Is there somewhere I can just add the path hardcoded?

At the top of your app you could do

$LOAD_PATH.unshift ENV[‘GEM_HOME’] unless $LOAD_PATH.include?
ENV[‘GEM_HOME’]

for a nasty workaround.

As for how $LOAD_PATH is built: well, it’s in ruby.c (look for incpush
and push_include), but the bits you’re looking at are probably added by
rubygems.

On 3 Sep 2010, at 09:14, Brian C. wrote:

Iain B. wrote:

Is there somewhere I can just add the path hardcoded?

At the top of your app you could do

$LOAD_PATH.unshift ENV[‘GEM_HOME’] unless $LOAD_PATH.include?
ENV[‘GEM_HOME’]

for a nasty workaround.

I shudder less at this

As for how $LOAD_PATH is built: well, it’s in ruby.c (look for incpush
and push_include), but the bits you’re looking at are probably added by
rubygems.

than at the thought of dealing with C :slight_smile:

On 3 Sep 2010, at 02:38, Ryan D. wrote:

502 % grep -A1 ryand /etc/sudoers

Added by ryand:

Defaults env_keep += “GEM_PATH GEM_HOME”

You need to pay attention to where you put that. It HAS to be after the reset_env line or it obviously won’t work.

I don’t have a reset line, but here’s my sudoers.

sudoers file.

This file MUST be edited with the ‘visudo’ command as root.

See the sudoers man page for the details on how to write a sudoers

file.

Host alias specification

User alias specification

Cmnd alias specification

Defaults specification

Defaults env_keep += “GEM_PATH GEM_HOME”

Runas alias specification

User privilege specification

root ALL=(ALL) ALL
%admin ALL=(ALL) ALL
%iainuser ALL=(ALL) ALL

Uncomment to allow people in group wheel to run all commands

%wheel ALL=(ALL) ALL

Same thing without a password

%wheel ALL=(ALL) NOPASSWD: ALL

Samples

%users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom

%users localhost=/sbin/shutdown -h now

Last login: Thu Sep 2 18:34:01 on ttys002
501 % env | grep GEM
GEM_PATH=/Library/Ruby/Gems/1.8
502 % sudo bash
501 % env | grep GEM
GEM_PATH=/Library/Ruby/Gems/1.8

btw… are you sure you’ve exported your env vars?

I used the method Brian C. suggested in the other mail, but I get
the same with the one you’ve used here:

sudo zsh
env
(blah blah blah…)
GEM_HOME=/Users/iainuser/.gems
GEM_PATH=/Users/iainuser/.gems

sh -c ‘echo $GEM_HOME’
/Users/iainuser/.gems

sudo sh -c ‘echo $GEM_HOME’
/Users/iainuser/.gems

sudo sh -c ‘env’
(blah blah blah…)
GEM_HOME=/Users/iainuser/.gems
HOME=/Users/iainuser
GEM_PATH=/Users/iainuser/.gems

Here’s a relevant portion of my zprofile, with recent additions
included:

export RUBY_PLATFORM=darwin
export PLATFORM="$RUBY_PLATFORM"
export RUBY_VERSION=1.9
export GEM_HOME="$HOME/.gems"
export RUBYLIB="$GEM_HOME"
export GEM_PATH="$GEM_HOME"
export RUBYOPT=rubygems

Is there somewhere I can just add the path hardcoded? I don’t really care about configurability, I’m not moving my gems anywhere else soon.

Fix it correctly or don’t fix it at all. Anything else is just a headache delayed.

I agree, but sometimes you just want a headache tablet. Or anything that
comes on prescription, I hear that’s what all the top celebrities are
doing nowadays. Except for Paris Hilton. Not sure if she counts as a top
celebrity though. If she’d been caught with several prescriptions I
might change my mind about her…

Regards,
Iain

Iain B. wrote:

On 3 Sep 2010, at 09:14, Brian C. wrote:

$LOAD_PATH.unshift ENV[‘GEM_HOME’] unless $LOAD_PATH.include?
ENV[‘GEM_HOME’]

Is there a way I can get this to run every time anything goes through
ruby, not just things I’ve written?

Well, there’s

export RUBYOPT=-I/Users/iainuser/.gems
or
export RUBYOPT=-rmyfrig

(and then put your code in myfrig.rb somewhere which is always in
$LOAD_PATH,
like
/Library/Frameworks/Ruby.framework/Versions/1.9.2-p0/lib/ruby/site_ruby/1.9.1
)

As long as RUBYOPT propagates of course.

For a more fundamental question, why do you want /Users/iainuser/.gems
in your $LOAD_PATH anyway? Surely you want the lib dirs of the
individual gems, and you wouldn’t/shouldn’t put ruby files at the top
level?

B.

On 3 Sep 2010, at 09:14, Brian C. wrote:

$LOAD_PATH.unshift ENV[‘GEM_HOME’] unless $LOAD_PATH.include?
ENV[‘GEM_HOME’]

Is there a way I can get this to run every time anything goes through
ruby, not just things I’ve written?

Regards,
Iain

Finally got back to this, and for whatever reason, it just works now, so
something I did before I was away has fixed it.

Many thanks to Brian and Ryan for helping me out with this, I can now
remove a lot of those hacks I put in until it stops working and find out
why.

Regards,
Iain

On Sep 3, 2010, at 06:47 , Iain B. wrote:

I don’t have a reset line, but here’s my sudoers.

sudoers file.

Here is what my /etc/sudoers has. It has only the one documented
molestation by myself. Everything else is standard to Mac OSX:

Defaults specification

Defaults env_reset
Defaults env_keep += “BLOCKSIZE”
Defaults env_keep += “COLORFGBG COLORTERM”
Defaults env_keep += “__CF_USER_TEXT_ENCODING”
Defaults env_keep += “CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE”
Defaults env_keep += “LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME”
Defaults env_keep += “LINES COLUMNS”
Defaults env_keep += “LSCOLORS”
Defaults env_keep += “SSH_AUTH_SOCK”
Defaults env_keep += “TZ”
Defaults env_keep += “DISPLAY XAUTHORIZATION XAUTHORITY”
Defaults env_keep += “EDITOR VISUAL”

Added by ryand:

Defaults env_keep += “GEM_PATH GEM_HOME”

So, did you gut yours, or what? what’s the output from which sudo?

User privilege specification

root ALL=(ALL) ALL
%admin ALL=(ALL) ALL
%iainuser ALL=(ALL) ALL

you shouldn’t need %iainuser either if your user is set up as an admin.

Here’s a relevant portion of my zprofile, with recent additions included:

export RUBY_PLATFORM=darwin
export PLATFORM="$RUBY_PLATFORM"
export RUBY_VERSION=1.9
export GEM_HOME="$HOME/.gems"
export RUBYLIB="$GEM_HOME"
export GEM_PATH="$GEM_HOME"
export RUBYOPT=rubygems

Here is what I have:

501 % env | egrep “RUBY|GEM”
GEM_PATH=/Library/Ruby/Gems/1.8

Why do you have all that stuff? and why are you trying to force gems
into ~/.gems if that’s supported already?

What are you actually trying to do?