[Solved] Why Go environment variable is not displayed with printenv in zsh?

[Solved] Why Go environment variable is not displayed with printenv in zsh?

In this tutorial, we will learn about how to fix the issue “Why Go environment variable is not displayed with printenv in zsh“. If you are a beginner in Go and stuck in the same issue where you are unable to print or use the Go variables using the command printenv, then you are at the right place. I recently had faced the similar issue while developing a Go application and found different solution to fix the issue. Today, we will understand the root cause of the issue along with different ways to fix the issue. So, let us begin the tutorial.

 

Why Printenv Command does not print Go Variables?

Also Read: [Solved] zsh command not found brew in macOS

The printenv command in Unix-like operating systems prints the environment variables for the current user session. These environment variables are key-value pairs that can affect the behavior of processes on a system. They typically include system-wide settings, such as PATH (which directories to search for executables), HOME (the current user’s home directory), and many others.

Go environment variables related to the Go programming language (such as GOROOT and GOPATH), are not printed by printenv by default unless they have been explicitly set in the environment from which printenv is called. This behavior is consistent with how printenv treats all environment variables, not just those related to Go.

 

[Solved] Why Go environment variable is not displayed with printenv in zsh ?

Now that we understand the issue, let us now look at different ways to resolve this issue. In macOS, there exist a file called .zshrc in the user’s home directory. This is a shell configuration file which is used to add scripts to configure different settings. This file is loaded every time you start a new Zsh shell session. Therefore, any modifications you make to this file will be applied automatically each time you open a new terminal window or tab. We will also use this file to set our Go variables to make it available at a specific user level.

Prerequisite

  • macOS operating system installed.
  • Basic zsh command knowledge.
  • Admin user access.
  • Go installed.

Once you’ve added the script to your .zshrc file and saved the changes, you don’t need to manually reapply them in future sessions. Zsh will automatically execute the commands in your .zshrc file when you start a new shell session, ensuring that the Go environment variables are exported and available globally within your shell environment.

Method-1: Setting Variables in Shell Configuration Files

For Unix-like systems (Linux, macOS), you can set environment variables in shell configuration files. This is the most common method for individual users. Since I am using macOS, I will use .zshrc configuration file to set the Go variables. If you are on Linux, you can use .bashrc file instead.  To begin with, open your terminal and check the current logged in user using command whoami as shown below.

[email protected] ~ % whoami
coder

 

As you see, I am currently logged in as coder user. Next, execute the command go env to check if Go variables are accessible by the user ‘coder’. As you see, I have grep GOPATH variable to see the configured value to it using the go env command.

[email protected] ~ % go env
[email protected] ~ % go env | grep GOPATH
GOPATH='/Users/coder/go'

 

Next, to check if you can access the value of GOPATH variable (or any Go variable), use below command. It will return empty output on the console as right now these variables are not accessible at user level.

[email protected] ~ % echo $GOPATH
[email protected] ~ % echo $GOBIN

 

Similarly, if you execute the printenv command and grep for GO variables, it will return the empty output as printenv is unable to access any GO variable currently.

[email protected] ~ % printenv | grep GO

Let us now look at the changes which needs to be done to make the Go variables accessible at user level. To do so, follow the below steps.

 

Step-1: Open Zsh Configuration File

We typically add environment variables to .zshrc file for Zsh. Open this file in your preferred text editor. If you’re using the terminal, you can use an editor like nano or vim. For example:

[email protected] ~ % vi ~/.zshrc

 

NOTE:

Note: if file is not there, create the file using command touch  ~/.zshrc

 

Step-2: Add Commands to Export Go Environment Variables

In this step, add a small script which will execute the commands to export Go variables as shown below. Append the script to the end of.zshrc file.

while IFS='=' read -r name value; do
eval export "$name=$value"
done < <(go env | grep '=')

 

This script works as follows:

  • It reads the output of go env, filtering for lines that contain =, which indicates an assignment of a value to a variable.
  • IFS='=' sets the internal field separator to =, so read splits input based on this character into name and value.
  • eval export "$name=$value" is used to correctly handle values that might contain spaces or special characters, ensuring they’re exported properly.

 

Step-3: Apply the Changes

After adding the script to your .zshrc file, you need to apply the changes. You can do this by either restarting your terminal or sourcing your .zshrc file with the following command:

[email protected] ~ % source ~/.zshrc

 

Step-4: Verify

To verify that the Go environment variables have been exported correctly, you can use the printenv command and look for the Go-related variables, or directly check a specific variable like GOPATH, GOBIN etc. This should return the value of variables if there are no issues.

[email protected] ~ % printenv | grep GO
[email protected] ~ % printenv GOPATH

 

NOTE:

This approach will dynamically export the Go environment variables at the start of a new shell session. If you update your Go configuration and want those changes to be reflected in your shell environment variables, you will need to restart your terminal or source your .zshrc file again.

 

Method-2: System-wide Environment Settings

In Method-1, we saw how to configure Go variables to make is available for a specific user in the system. There is another way which is used to make the Go variables available at system wide, meaning make it available for all the users in the system. 

If you apply the changes to export Go environment variables in the /etc/profile file instead of the user-specific .zshrc file, it will affect all users on the system, not just your own user account. Here’s what will happen:

  1. Global Availability: The Go environment variables will be exported for all users who log in to the system. This means that any user who opens a shell session, regardless of whether they’re using Zsh or another shell, will have access to these environment variables.
  2. Higher Priority: Changes made to /etc/profile take precedence over user-specific configuration files like .zshrc. Therefore, if a user has their own custom settings in .zshrc, they will be overridden by the settings in /etc/profile.
  3. System-wide Impact: Modifying /etc/profile affects the system globally, which can be useful for ensuring consistency across all users’ environments. However, it also means that you need to be cautious when making changes, as they will affect all users and may have unintended consequences.
  4. Requires Administrator Privileges: Editing /etc/profile typically requires root or administrator privileges. You’ll need to use sudo or another method to gain elevated permissions in order to modify this file.
  5. Persistence Across Sessions: Changes made to /etc/profile will persist across system reboots and terminal sessions for all users, ensuring that the Go environment variables are consistently available.

Overall, applying these changes to /etc/profile can be appropriate if you want to ensure that the Go environment variables are available to all users on the system and if you have the necessary permissions to modify system-wide configuration files. However, you should exercise caution and consider the potential impact on all users before making such modifications.

To make above changes, follow below steps in sequential order.

 

Step-1: Switch to Another User

Switch to another user using command su - <user-name>. Print the GOPATH variable value using echo as shown below. It will not print any output. This is because we have not set the Go variables globally.

[email protected] ~ % su - stack
[email protected] ~ % echo $GOPATH

 

Step-2:  Add Commands to Export Go Variable in /etc/profile File

The /etc/profile file is a system specific file and hence is owned by root user in the system. To modify this file, switch to root user as shown below.

[email protected] ~ % sudo su
Password:
sh-3.2#

 

Next, open /etc/profile file and add below commands at the end of the file.

sh-3.2# vi /etc/profile

# Export Go environment variables
go_env_output=$(go env)
IFS=$'\n'
for line in $go_env_output; do
if [[ $line == *=* ]]; then
name=$(echo "$line" | cut -d= -f1)
value=$(echo "$line" | cut -d= -f2-)
export "$name=$value"
fi
done
unset IFS

Save the file and exit using the command :wq!

 

Step-3: Source the File

For immediate effect, source the file /etc/profile in current terminal session using below command.

sh-3.2# source /etc/profile

 

Step-4: Reboot the System

For making the changes persistent, reboot your machine after which all the user account in the system will now be able to read the Go variables.

sh-3.2# reboot

 

Summary

We have successfully fixed the error using one of the given methods in this tutorial. Remember that the given methods are used based on the use case and requirement. For example, it is not necessary to make the Go variables available for all the users in the system until required.

Leave a Comment