Zsh is a shell program like bash. While it has many improvements and features that bash doesn’t have – like autocompletion and improved history navigation – bash is still the standard shell everyone is used to. You can mostly run bash scripts in zsh without any change since it’s designed to be compatible. Regarding setting environment variables, the two shells are almost alike except for a few key differences as shown below.
Installing zsh
If you’re used to bash, then installing and using zsh will be simple. Just type the following:
sudo apt update
sudo apt install zsh -y
This will install zsh. Once done, check the zsh version:
zsh --version
If you see a version number, it means zsh is properly installed. You can get started using zsh by typing:
zsh
If this is the first time you’re using zsh, you’ll see something like this:
I find it easiest to get started by choosing the (2) option, which populates .zshrc with basic defaults and lets you start using zsh immediately.
The prompt for zsh is quite different from what you see in bash, as you can see here:
As you can see, it’s quite different from what you see in bash by default. In bash, you’ll get something like this:
user@hostname:~$
zsh uses the percentage (%) symbol instead of the dollar ($) sign.
How Environment Variables work in zsh
The syntax for setting environment variables in zsh is pretty much the same in zsh as it is in bash. For example, I’m going to create a variable called “$test” and assign it a value like this:
test="This is a test"
Then you can use the $test variable in your commands like this:
You can also use the “export” command like this:
export test="This is a test"
And you could also do the two separately:
test="This is a test"
export test
In bash, exporting a variable makes it available globally to other scripts, whereas zsh makes all variables available in the global context automatically.
Creating a Permanent Variable
However, the above commands will only create a variable for the current session. If you want your variable to persist between sessions and reboots, you need to add it to the .zshrc file.
The command to do that is:
echo 'export VAR_NAME="value"' >> ~/.zshrc
The ~/.zshrc file is a hidden file that contains the configuration for zsh, just like the .bashrc file is the configuration file for bash. It’s run whenever a new zsh shell is started and it applies all your customizations. Similar to .bashrc, when you make a change to the file and want your changes to be immediately applied, type the following:
source ~/.zshrc
This way, you can apply your changes without having to restart zsh and lose your existing session.
Unsetting a Variable
Finally, if you need to, you can “unset” an environment variable with zsh like this:
unset VAR_NAME
However, the above command will only unset it for the current session. If you’ve set a variable via the .zshrc file, then you’ll need to undo the changes you’ve made there by either deleting or commenting out the line that sets the variable.
You can always check and see if an existing variable is set via the following command:
printenv MY_VAR
or
echo $MY_VAR
If you get an output from either of the two commands, then the variable is set. Otherwise, no.
Making zsh Variables Global
When you declare a variable in zsh, it remains local to the shell and isn’t made available to other processes. For example, take the following code:
test="hey there"
zsh -c 'echo $test'
Here’s the output:
You can see that nothing is printed. This is because the “test” variable that was declared in zsh isn’t available to any new sub-process, even if that’s another zsh shell. This means that if you’re writing scripts in zsh, and you want to use variables between various processes, you must use the “export” command. For example:
export test="hey there"
zsh -c 'echo $test'
And here’s the output:
Using /etc/zshenv to Declare Variables
For variables that you want to declare automatically, zsh has a feature whereby you can declare them in a separate file called:
/etc/zshenv
This file is loaded whenever zsh starts up and so you can declare all your commonly used variables inside it. However, it’s a common misconception that variables declared in this file are automatically available to all processes. The truth is that /etc/zshenv variables are sourced to every new zsh session, but not non-zsh subprocesses.
It’s a subtle difference, and easy to miss. If you want your variables inside /etc/zshenv to be made available to all processes, then you must use the “export” declaration like everywhere else.
When to Use /etc/zshenv and ~/.zshrc
We’ve already seen that the ~/.zshrc file is loaded for every new zsh session. Given that you can use this file to automatically declare variables whenever a shell starts, why would you choose to use another file like /etc/zshenv to declare your variables?
The difference lies in the scope of the variables. ~/.zshrc is located in the user profile folder for each user, and every user has a different .zshrc file. This means that you can customize the behavior of zsh on a per-user basis. /etc/zshenv on the other hand, is a global location and the same file runs for all users. This means that there’s no customization between users, so it’s less personal.
Another difference lies in the types of processes to which the variables are applied. In ~/.zshrc, the variables are made available only to interactive shells – in other words, when the shell is opened manually by another user. The variables in /etc/zshenv on the other hand, are made available to all zsh shells, regardless of whether they were opened manually or not. This means that even if you open a zsh shell programmatically in a non-interactive setting, it’ll have access to the variables declared in /etc/zshenv.
Temporary Variables in zsh
Sometimes, in scripts, you might need to create temporary variables that persist only for the duration of a single command. There could be multiple reasons for this. Perhaps you don’t want to change the shell environment permanently. Or you could pass a new configuration variable just for a single command, like a $PATH variable, for instance. It could even be for security reasons, where you don’t want to store sensitive information like a password or an API key on the system.
You can create a temporary variable for a single command like this:
env test="hello" bash -c 'echo $test'
Here’s how it works:
You can see that the command works just once. When I try and access the “test” variable again outside the initial command, it shows a blank. This way, you can create temporary variables for all sorts of situations without messing up the global environment.
Conclusion
As shown, the basic functionalities of setting variables in zsh are the same as in bash. There are barely any differences, and when they do exist, they’re so nuanced that they manifest only in edge-case scenarios. If you’re used to bash, then you won’t have any problems getting started with variables in zsh, because the latter is designed to be backward compatible with bash

I’m a NameHero team member, and an expert on WordPress and web hosting. I’ve been in this industry since 2008. I’ve also developed apps on Android and have written extensive tutorials on managing Linux servers. You can contact me on my website WP-Tweaks.com!
Leave a Reply