I use a script (which I do not have write access to) that creates a bunch of aliases to set up an environment. I would like to create a bash function to setup my environment, but it seems that the aliases do not survive to the function body.
Here's a minimal example:
# aliases.sh
alias fooAlias='echo "this will never work!"'
.
# .bashrc
function setupLotsOfThings() {
source aliases.sh
fooAlias
}
.
Now, if I simply source aliases.sh
interactively, things work as expected:
[mycomputer]~/ $ source aliases.sh
[mycomputer]~/ $ fooAlias
this will never work!
However, if I instead call the function defined in my .bashrc, it doesn't recognize the alias after sourcing its definition:
[mycomputer]~/ $ setupLotsOfThings
-bash: fooAlias: command not found
What is going on here? Is there something I am missing about the scope of the alias
command when used in a function?
Edit: I'll add some details beyond the minimal example to shine some light on what I'm trying to accomplish.
For my work I develop and run a lot of software on a cluster and/or grid. I have several projects that require completely different environments, such as different gcc versions, specific software releases, config and data PATHs, and various environment variables. Administrators provide the scripts to set up various things, usually by defining shell functions or aliases, which invoke other functions or aliases or run various scripts. To me, it's a black box.
I'd like to setup my own various environments with a single command. Currently, I do something like:
[mycomputer]~/ $ source /some/environment/setup/script.sh
[mycomputer]~/ $ aliasToSetupSomeSoftwareVersion #this was defined in the above
[mycomputer]~/ $ anotherAliasForOtherSoftware
[mycomputer]~/ $ source /maybe/theres/another/script.sh
[mycomputer]~/ $ runSomeOtherSetup # this was defined in the new script
These commands generally have to be run in order. My idea basically was to just copy the above lines into a function block, but as original example shows, that simply doesn't work. Alternative workarounds are more than welcome!
Best Answer
An alternative solution is to paste those commands into a text file instead of a function block. Something like:
Save that as
setup1.sh
wherever you like. The trick is to then source this file, not execute it:That will run the aliases that are in the script and also make them available to your current shell.
You can further simplify the process by adding this to your
.bashrc
:Now you can simply run
setupLotsOfThings
and get the behavior you wanted from the function.Explanation
There are two issues here. First, aliases are not available to the function they are declared in but only once that function has exited and second that aliases are not available within scripts. Both are explained in the same section of
man bash
:Then, there is the difference between executing and sourcing a file. Basically, running a script makes it run in a separate shell while sourcing it makes it run in the current shell. So, sourcing
setup.sh
makes the aliases available to the parent shell while executing it as a script would not.