I'm not sure but I think the following behavior is kind of inconsistent. Setting the environment works different on functions and program. Case 1 and 2 export a variable before calling the env program. In case 2 copying the assignment of HELLO works as expected. Case 3 and 4 export a variable before calling a function which calls the env program. In case 4 copying the the assignment of HELLO doesn't work because HELLO is assigned to $HELLO but assigning HELLO to $WORLD (case 3) works. Any reason why zsh behaves this way? Bash doesn't have this strange behavior. ## 1: export to command (different variable) $ WORLD=world $ HELLO=$WORLD env | grep '^HELLO' HELLO=world ## 2: export to command (same variable) $ HELLO=world $ HELLO=$HELLO env | grep '^HELLO' HELLO=world ## 3: HELLO exported to shell function, same behavior as 1 $ call() { env | grep '^HELLO' } $ WORLD=world $ HELLO=$WORLD call HELLO=world ## 4: HELLO not exported to shell function, different from 2 and 3 $ call() { env | grep '^HELLO' } $ HELLO=world $ HELLO=$HELLO call HELLO= ## <-- empty