Bashrc lazy substitution

aliasbashbashrcquotingshell

How does one get ~/.bashrc aliases to evaluate $() substitutions at run time, instead of at the time that ~/.bashrc is executed (when opening a terminal)?

I run this command often enough that I would like to add an alias for it:

svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff

However, when I add it to ~/.bashrc as an alias, I see that the evaluations are hard-coded to the values they had at the time I opened the terminal:

$ alias
alias svnbranch='svn diff -r 178184:HEAD svn+ssh://branches/t4252 | colordiff'

If I open a terminal in ~ then I get errors:

svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
$ alias
alias svnbranch='svn diff -r :HEAD  | colordiff'
$

I've tried these two variations of the alias in ~/.bashrc, they both have the same effect (as I expected):

alias svnbranch="svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff"
alias svnbranch="svn diff -r `svn info | grep ^Revision | awk {'print $2'}`:HEAD `svn info | grep ^URL | awk {'print $2'}` | colordiff"

How does one get ~/.bashrc aliases to evaluate $() substitutions at run time?

Additionally, how would one search for this situation in Google? I've tried to google on "bashrc substitution", "bashrc lazy substitution", and other key phrases, but I've found nothing for what I feel should be a common enough issue to find information on.

Best Answer

Use single quotes to suppress processing of special characters. You could also backslash the $s.

For a complex command you are probably better off using a function in any case, which doesn't require any escaping and is easier to read and edit:

svnbranch() {
    svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff
}

You can define a function anywhere you could define an alias.

Related Question