views:

314

answers:

3

OSX: This works from the command line: alias ruby="/opt/local/bin/ruby1.9"

but in side a shell script, it has no effect. I want to write a script that will switch between ruby 1.8 and ruby 1.9, so this needs to be a script - not in my profile.

It appears "source script.sh" works, but "./script.sh". Why is this? How can I replicate this in my script?

thanks!

+5  A: 

./script.sh will be executed in a sub-shell and the changes made apply only the to sub-shell. Once the command terminates, the sub-shell goes and so do the changes.

sourcing the file using . ./script.sh or source ./script.sh will read and execute commands from the file-name argument in the current shell context, that is when a script is run using source it runs within the existing shell, any variables created or modified by the script will remain available after the script completes.

codaddict
+2  A: 

You can write a function in your .profile to switch the aliases

function toggle-ruby() {
  if [ "$1" == "1.9" ]; then
    alias ruby=/opt/local/bin/ruby1.9
  else
    alias ruby=/opt/local/bin/ruby1.8
  fi
}

then run you can run:

toggle-ruby 1.9

or

toggle-ruby 1.8

to switch back and forth.

Dave Bacher
this is a good approach. thanks!
phil swenson
A: 

The simple answer for you is that scripts create non-interactive shells and, by default, the expand_aliases option is often disabled.

You can fix this very simply by just adding the following line to the top of your script to enable the alias expansion:

shopt -s expand_aliases

This problem has been bugging me, so I did research and then wrote a blog post once I figured out how to fix it for myself: Post about using alias from within Linux shell scripts.

Of course, right after I figured out that part, I found that, while it works for what you need, it will not work if you have a subshell within a a subshell. I am still looking into the fix for that problem, that is how I just came across your question. On the blog post, I mention a cheap hack that I use to grab the alias in a shell script. It isn't elegant, but it actually works even in this multiple subshell problem I have.

SiteMonger