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?

  • 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 '16 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 – Amelio Vazquez-Reina Mar 30 '16 at 18:19
  • What whence -f do_something outputs? – user17530 Mar 30 '16 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 '16 at 18:24
  • Run set -x in zsh, set FROM and call do_something. Add the output to your answer – user17530 Mar 30 '16 at 18:36
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.

| improve this answer | |
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.

| improve this answer | |

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.