6

I want to update my aliases from a script.

I have some new aliases in ~/updateFiles/newAliases:

alias ga='git add -A'

I also have this update script ~/updateFiles/updater:

#!/bin/bash
cp newAliases ~/.bash_aliases
source ~/.bash_aliases

But it does not appear to work. How do I get the calling environment to source the new aliases?

This does not work:

$ cd ~/updateFiles
$ ./updater
$ ga
-su: ga: command not found

This does work:

$ cd ~/updateFiles
$ ./updater
$ source ~/.bash_aliases
$ ga
$
9

The difference is the scope and syntactically is very subtle:

$ ./updater

is the equivalent of

$ /bin/bash ./updater

It runs the script (if it is marked as executable and on a filesystem mounted with the exec option - the latter form works even if one of these conditions is not met). That means it spawns new shell instance and feeds it content of the script. Thus any aliases defined therein are limited to the duration of the interpreting shell which is only till the end of the script.

$ . updater
$ . ./updater
$ source updater
$ source ./updater

mean all the same and tell the current shell to execute contents of that file as if you typed it on the command line. That means that any aliases, functions, environment variables, shell option settings and so on will be available in the shell afterwards.

That is also why you sometimes see shell init files (~/.bashrc in the case of Bash) that look like this:

#!/bin/bash
for n in ~/etc/bash/*; do
    . $n
done

where ~/etc/bash can look like:

~/etc/bash/
|-- bash.10.env
|-- bash.20.aliases
`-- bash.30.func

(the names are quite self-explanatory). Whenever you add some files to such init directory, all you need to do to apply the changes is . ~/.bashrc. For which you can have an alias, of course. This can be also extended - for example by having specialised initialisation depending on the hostname (or phase of moon by using pom from bsg-games).

One big caveat for these setups: be sure to make the the init files "re-entrant" in the sense it doesn't matter how many times you source them in one shell - for example variables you may want to preserve should be defined conditionally:

VAR=${VAR:-"value"}

instead of unconditionally:

VAR="value"
| improve this answer | |
  • So the main difference is that you are sourcing a script that will update variables/aliases in the current shell vs (what the OP was doing) running a script which starts a new shell that then sources i.e. doesn't update the current shell. – Robert Mark Bram Oct 1 '14 at 8:56
  • Quite a subtle difference, but exactly what I was looking for. Thanks! – hoosierEE Oct 1 '14 at 14:16
8

You have to source the file otherwise the aliases have a very short lifespan: the duration of the invoked shell.

I have this in my .bashrc:

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

to read in the aliases. And this alias:

alias realias='source ~/.bash_aliases'

at the beginning of my .bash_aliases file. After an update I just issue the realias command.

| improve this answer | |
6

I don't think you can't do it with a script. To use a script, you would have to source it, not execute as others have explained. Another approachis to use a function. Add these lines to your ~/.bashrc:

updater(){
    cp ~/newAliases ~/.bash_aliases
    source ~/.bash_aliases
}

Then, run updater and your aliases will be renewed and sourced.

| improve this answer | |
  • I think it'd be better to give a full path to newAliases, otherwise that function will take whatever "newAliases" file that happens to be in the current dir, or barf that it doesn't find any in current dir – Olivier Dulac Oct 1 '14 at 8:17
  • @OlivierDulac that is a full path. – terdon Oct 1 '14 at 8:30
  • I see "cp newAliases ~/.bash_aliases" ? newAliases is in the current dir – Olivier Dulac Oct 1 '14 at 8:39
  • 1
    @OlivierDulac that's because I should learn not to answer comments before coffee. You're absolutely right of course, I was thinking of ~/.bashrc which is a full path. Thanks, answer edited. – terdon Oct 1 '14 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.