Tarrenam
Tarrenam

Reputation: 382

bash - how is * interpreted in aliases?

[Note - I solved the problem I ran into using a bash function, but I want to understand why my initial attempt didn't work.]

I run git in Windows, and use the Git Bash command line application to manage repositories. I have several repositories that I often want to pull all at once. Previously I was doing this just by entering the following on the command line:

for i in *; do cd $i; git pull --rebase; cd ..; done;

To save time, I decided to create an alias for this. So, I created a .bashrc file in the home directory (C:/git in my case) and added the line

alias pr="for i in *; do cd $i; git pull --rebase; cd ..; done;"

However, this didn't work at all, the output was

sh.exe" cd: /etc/profile.d/*.sh: No such file or directory

followed by git complaining that it wasn't in a repository. The output would be repeated over 20 times for a single call. The root of the MinGW filesystem, where the /etc above derives from, is where I installed git to (C:/Program Files (x86)/Git).

Now, I solved this problem in the end by creating a function in my .bashrc file instead, like so:

pr(){
    for i in *
    do
        cd $i
        git pull --rebase
        cd ..
    done
}

So, my problem is solved, but I do want to understand why my initial approach didn't work. There's clearly something about aliases I don't understand that is, presumably, mangling the 'i in *' bit. My expectation was that bash would substitute the string the alias maps to and then evaluate it, but it doesn't seem to be that straightforward.

Upvotes: 2

Views: 101

Answers (1)

Karel Kubat
Karel Kubat

Reputation: 1675

I haven't analyzed this in full, but it has to do with the time at which your $i in the alias gets expanded. The way you're doing this, $i will probably be initialized during alias creation. In the function version, it will be interpreted at run-time. Try defining the alias as you've shown, then run:

alias pr  # show how the alias is defined

Bash will happily postpone expansion of $-variables if you define the alias with single quotes. The following should work as well as your function.

alias pr='for i in *; do cd $i; git pull --rebase; cd ..; done;'

Upvotes: 6

Related Questions