74

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?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
phil swenson
  • 8,564
  • 20
  • 74
  • 99

4 Answers4

121

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.

mahemoff
  • 44,526
  • 36
  • 160
  • 222
JoeB
  • 1,538
  • 1
  • 11
  • 9
  • 11
    This is a much better answer than the accepted one. If you've landed here from a search this one is probably what you want. – bahamat Jan 17 '13 at 20:42
  • 5
    even though I don't this is what the OP intended, it is exactly what I was searching for! thanks – Filipe Pina Feb 06 '13 at 12:09
  • 1
    The best answer. You should add this top of your bash script, not ~/.bash_profile. – Inanc Gumus Jun 18 '14 at 15:19
  • 1
    Not work on ubuntu 14.04. I want script to change my alias. But it just change alias during script running. – Mithril Dec 31 '15 at 07:15
  • 1
    The accepted answer works, while this doesn't. Also Ubuntu 14.04. – AlwaysLearning May 18 '16 at 12:42
  • This answer doesn't make sense in question context. Either question title or this answer should be changed. – sobi3ch Jun 15 '16 at 17:41
  • -1 this does not answer the OP's question at all. If you are one of the people who found this answer helpful, what is the question that you had? Maybe post it as a separate Q/A. – Stephen Apr 02 '18 at 16:27
  • 3
    just saying the obvious out loud, this is a great answer to a completely different question. Matching question would be: `Why is the alias command not working inside a bash script` and it's already here: https://askubuntu.com/questions/98782/how-to-run-an-alias-in-a-shell-script – papo Nov 20 '18 at 09:46
  • 1
    Your article you linked to is well-written, but it seems that it solves a different problem than what OP is asking. OP is trying to use a subshell or child process to modify the alias list of the parent, whereas your article (by way of `shopt -s expand_aliases`) affects the alias behavior of the subshell/child only. – flow2k Feb 07 '19 at 19:48
86

./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
  • 445,704
  • 82
  • 492
  • 529
8

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
  • 15,652
  • 3
  • 63
  • 86
7

If you need to switch Ruby versions, try rvm.

Adam Lear
  • 38,111
  • 12
  • 81
  • 101
zwal se konia
  • 71
  • 1
  • 1