3

Say we define the following shell function and alias in .zshenv:

export VARIABLE_A='original'

function my_function()
{
    print $VARIABLE_A
}

export VARIABLE_B='original'

alias my_alias="print $VARIABLE_B"

Now, say that we start a new interactive shell, and we do the following:

$ my_function
$ export VARIABLE_A='new'
$ my_function


$ my_alias
$ export VARIABLE_B='new'
$ my_alias

The commands above print:

original
new
original
original

It looks like the function is updated, but the alias isn't. Is this behavior expected? And if so, why?

7
  • I am not familiar with zsh but instead of export $FROM=/new/path, did you try it with just FROM=/new/path ?
    – MelBurslan
    Mar 30, 2016 at 18:18
  • @MelBurslan that was just a temporary typo (I actually corrected it 7 minutes before your comment (?)). I am using FROM=/new/path Mar 30, 2016 at 18:19
  • What whence -f do_something outputs?
    – user17530
    Mar 30, 2016 at 18:23
  • I did somethng similar in bash. My payload is just echo ${variable} instead of your rsync and it worked as expected for me. caching (for the lack of a better analogy) might be a zsh feature
    – MelBurslan
    Mar 30, 2016 at 18:24
  • Run set -x in zsh, set FROM and call do_something. Add the output to your answer
    – user17530
    Mar 30, 2016 at 18:36

2 Answers 2

3

Yes, the behavior is expected. The reason being simply that you used double quotes ("…") when defining the alias, allowing for parameter substitution. This led to $VARIABLE_B being substituted at the time of the definition of the alias instead of its execution.

Essentially, when writing

VARIABLE_B="original"
alias my_alias="print $VARIABLE_B"

zsh will replace $VARIABLE_B before running the alias command like so:

alias my_alias="print original"

Therefore the alias my_alias will always be replaced with print original before execution.

If you want to substitute a parameter at execution time you have to quote it, either with single quotes ('…') or by quoting $ with a \:

alias my_alias='print $VARIABLE_B'
alias my_alias="print \$VARIABLE_B"

This will set the alias so, that the variable name remains part of the command and the alias my_alias is actually replaced with print $VARIABLE_B before execution.


In contrast parameters inside a function definition do not need to be quoted explicitly, they are always only substituted at runtime.

So when writing

my_function () {
{
    print $VARIABLE_A
}

this is exactly what will be stored. When running my_function $VARIABLE_A will be substituted with the value it has at that time.

0

Say we define the following shell function and alias in .zshenv:

Aliases are evaluated on execution of a script. So $VARIABLE_B is evaluated and replaced with its value at the moment when your .zshenv is processed. Whatever value you will assign to VARIABLE_B later is not going to affect the alias.

On the contrary functions do not evaluate enviroment variables when they are processed. Enviroment variables in function are evaluted when a function is called.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .