Environment variables can be thought of as a name value pair that affect the behavior of the processes running on an operating system.
For example, to know the value of environmental variable PATH in my system, I do :
Now, why do we need environment variables?
Suppose you created a program that creates some temporary files. The program should create temporary files in some standard path of the system which is used for storing temporary files. Now, your program is not restricted to run on one single computer system. It can run on multiple systems. It is very well possible that the standard path for temporary files is different for different systems. So what would your program do to create temporary files at the standard path for the system its running on??
Well, in this situation environment variables come to rescue. The program can access the value of corresponding environment variable and creates the temporary files at that path.
Inside the code, the environment variables can be accessed by :
1) Accepting a third argument 'environ' to the main function.
This way of declaring 'main()' has been deprecated by ISO C.
2) Accessing a global variable environ.
This way is preferred over the way described in point 1 above.
Lets understand the above mentioned ways through an example :
1) The code below uses the older declaration of main() function to access environment variables :
When the above code is run, I get the following output on my machine :
So we can see that all the environment variables for my system are displayed.
2) The code below uses the global variable 'environ' :
Note that we need to declare the variable 'environ' as extern so that code gets compiled without any errors.
Now, when I run the code, I get :
What if in the code, you want to get value of a particular environment variable ?
Well, 'getenv()' function is there to help you. The signature of the function is :
From the man page of this function :
Lets see how it works :
When the above code is executed, we see :
So we see that through the function 'getenv()' we successfully fetched the value of environment variable PATH. Similarly we can get the value of any environment variable we desire.
What if from within the code you want to create a new environment variable or change value of an existing environment variable?
Well, this can be done achieved using the 'putenv' or 'setenv' functions.
From the man page of putenv function :
Here is the code which tries to create an environment variable MYENVAR with value /home/himanshu/
When the above code is run, the output we get is :
So we see that through the function putenv() we successfully added an environment variable to the environment.
Next up lets try to change the value of existing variable MYENVAR.
Here is the code to achieve this :
In the above code, we first check whether there already exists an environment variable named MYENVAR. If not then we create one with a value and then we change its value. Now, lets see what happens when we run the above code :
The output shows that through putenv() function the value of the environment variable is changed easily.
Now, we can also add/change an environment variable with function setenv(). Lets see how :
In the above code, we have used the function setenv() and set the value of third argument as '1' when we wanted to update its value.
Lets see the output :
In the above output we see that through setenv() function too we are able to add/modify an environment variable.
Please note that if you set/change an environment variable using the above shown techniques. The persistence of that particular change is temporary. If a new environment variable is added through code, its visibility remains up till the code is running. As soon as the process terminates, the environment variable is cleared.
To make permanent changes put the new environment string at the end of the .profile, or .bash_rc or .bash_profile file, depending on your distribution.
To conclude, this article demonstrates the use of environment variables, how to access them through code. Also, how we can fetch the value or change the value of existing environment variable through C functions.
Stay tuned for more...
For example, to know the value of environmental variable PATH in my system, I do :
Code:
-laptop ~ $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Suppose you created a program that creates some temporary files. The program should create temporary files in some standard path of the system which is used for storing temporary files. Now, your program is not restricted to run on one single computer system. It can run on multiple systems. It is very well possible that the standard path for temporary files is different for different systems. So what would your program do to create temporary files at the standard path for the system its running on??
Well, in this situation environment variables come to rescue. The program can access the value of corresponding environment variable and creates the temporary files at that path.
How to access env variables
Inside the code, the environment variables can be accessed by :
1) Accepting a third argument 'environ' to the main function.
Code:
int main(int argc, char *argv[], char **environ)
OR
int main(int argc, char *argv[], char *envp[])
2) Accessing a global variable environ.
This way is preferred over the way described in point 1 above.
Lets understand the above mentioned ways through an example :
1) The code below uses the older declaration of main() function to access environment variables :
Code:
#include<stdio.h>
int main(int argc, char *argv[], char *envp[])
{
int i = 0;
while(envp[i] != NULL)
{
printf("\n [%s] \n",envp[i]);
i++;
}
printf("\n Done...exiting\n");
return 0;
}
Code:
~/practice $ ./environ [ORBIT_SOCKETDIR=/tmp/orbit-himanshu] [SSH_AGENT_PID=1695] [TERM=xterm] [SHELL=/bin/bash] [XDG_SESSION_COOKIE=b8b52be9a0280f3c8b48fcf04d7ac5a3-1320743817.969365-1067214140] [WINDOWID=20971760] [GNOME_KEYRING_CONTROL=/tmp/keyring-aob7hd] [GTK_MODULES=canberra-gtk-module] [USER=himanshu] [SSH_AUTH_SOCK=/tmp/keyring-aob7hd/ssh] [DEFAULTS_PATH=/usr/share/gconf/gnome.default.path] [SESSION_MANAGER=local/himanshu-laptop:@/tmp/.ICE-unix/1661,unix/himanshu-laptop:/tmp/.ICE-unix/1661] [USERNAME=himanshu] [XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg] [DESKTOP_SESSION=gnome] [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games] [PWD=/home/himanshu/practice] [GDM_KEYBOARD_LAYOUT=us] [LANG=en_IN] [GNOME_KEYRING_PID=1643] [MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path] [GDM_LANG=en_IN] [GDMSESSION=gnome] [SPEECHD_PORT=7560] [SHLVL=1] [HOME=/home/himanshu] [GNOME_DESKTOP_SESSION_ID=this-is-deprecated] [LOGNAME=himanshu] [XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/] [DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-tuOHkHOhpc,guid=5a9c7ce1bf45d031130517354eb8f38a] [DISPLAY=:0.0] [XAUTHORITY=/var/run/gdm/auth-for-himanshu-UPXg4a/database] [COLORTERM=gnome-terminal] [_=./environ] [OLDPWD=/home/himanshu] Done...exiting
2) The code below uses the global variable 'environ' :
Code:
#include<stdio.h>
extern char **environ; // Need to declare it at least
int main(int argc, char *argv[])
{
int i = 0;
while(environ[i] != NULL)
{
printf("\n [%s] \n",environ[i]);
i++;
}
printf("\n Done...exiting\n");
return 0;
}
Now, when I run the code, I get :
Code:
~/practice $ ./environ [ORBIT_SOCKETDIR=/tmp/orbit-himanshu] [SSH_AGENT_PID=1695] [TERM=xterm] [SHELL=/bin/bash] [XDG_SESSION_COOKIE=b8b52be9a0280f3c8b48fcf04d7ac5a3-1320743817.969365-1067214140] [WINDOWID=20971760] [GNOME_KEYRING_CONTROL=/tmp/keyring-aob7hd] [GTK_MODULES=canberra-gtk-module] [USER=himanshu] [SSH_AUTH_SOCK=/tmp/keyring-aob7hd/ssh] [DEFAULTS_PATH=/usr/share/gconf/gnome.default.path] [SESSION_MANAGER=local/himanshu-laptop:@/tmp/.ICE-unix/1661,unix/himanshu-laptop:/tmp/.ICE-unix/1661] [USERNAME=himanshu] [XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg] [DESKTOP_SESSION=gnome] [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games] [PWD=/home/himanshu/practice] [GDM_KEYBOARD_LAYOUT=us] [LANG=en_IN] [GNOME_KEYRING_PID=1643] [MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path] [GDM_LANG=en_IN] [GDMSESSION=gnome] [SPEECHD_PORT=7560] [SHLVL=1] [HOME=/home/himanshu] [GNOME_DESKTOP_SESSION_ID=this-is-deprecated] [LOGNAME=himanshu] [XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/] [DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-tuOHkHOhpc,guid=5a9c7ce1bf45d031130517354eb8f38a] [DISPLAY=:0.0] [XAUTHORITY=/var/run/gdm/auth-for-himanshu-UPXg4a/database] [COLORTERM=gnome-terminal] [_=./environ] [OLDPWD=/home/himanshu] Done...exiting
How to fetch a particular env variable?
What if in the code, you want to get value of a particular environment variable ?
Well, 'getenv()' function is there to help you. The signature of the function is :
Code:
char *getenv(const char *name);
DESCRIPTIONSuppose we want to fetch the value of environment variable PATH using this function.
The getenv() function searches the environment list to find the environment variable name, and returns a pointer to the corresponding value
string.
RETURN VALUE
The getenv() function returns a pointer to the value in the environment, or NULL if there is no match.
Lets see how it works :
Code:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
char *val = getenv("PATH");
printf("\nValue of environment variable PATH is [%s]\n",val);
return 0;
}
Code:
$ ./environ Value of environment variable PATH is [/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games]
How to set value to a particular env variable?
What if from within the code you want to create a new environment variable or change value of an existing environment variable?
Well, this can be done achieved using the 'putenv' or 'setenv' functions.
From the man page of putenv function :
NAMEFrom the man page of setenv function :
putenv - change or add an environment variable
SYNOPSIS
#include <stdlib.h>
int putenv(char *string);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
putenv(): _SVID_SOURCE || _XOPEN_SOURCE
DESCRIPTION
The putenv() function adds or changes the value of environment variables. The argument string is of the form name=value. If name does not
already exist in the environment, then string is added to the environment. If name does exist, then the value of name in the environment is
changed to value. The string pointed to by string becomes part of the environment, so altering the string changes the environment.
RETURN VALUE
The putenv() function returns zero on success, or non-zero if an error occurs.
NAMELets take a couple of examples as a proof of concept to the above explanations.
setenv - change or add an environment variable
SYNOPSIS
#include <stdlib.h>
int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
setenv(), unsetenv(): _BSD_SOURCE || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
DESCRIPTION
The setenv() function adds the variable name to the environment with the value value, if name does not already exist. If name does exist in the
environment, then its value is changed to value if overwrite is non-zero; if overwrite is zero, then the value of name is not changed. This func-
tion makes copies of the strings pointed to by name and value (by contrast with putenv(3)).
RETURN VALUE
The setenv() function returns zero on success, or -1 on error, with errno set to indicate the cause of the error.
Here is the code which tries to create an environment variable MYENVAR with value /home/himanshu/
Code:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
if(putenv("MYENVAR=/home/himanshu"))
{
printf("\n putenv() failed\n");
return 1;
}
printf("\n Successfully Added a new environment variable\n");
char *val = getenv("MYENVAR");
printf("\nValue of environment variable MYENVAR is [%s]\n",val);
return 0;
}
Code:
~/practice $ ./environ Successfully Added a new environment variable Value of environment variable MYENVAR is [/home/himanshu]
Next up lets try to change the value of existing variable MYENVAR.
Here is the code to achieve this :
Code:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
char *val = getenv("MYENVAR");
if(val == NULL)
{
if(putenv("MYENVAR=/home/himanshu"))
{
printf("\n putenv() failed\n");
return 1;
}
val = getenv("MYENVAR");
}
printf("\nCurrent value of environment variable MYENVAR is [%s]\n",val);
if(putenv("MYENVAR=/home/himanshu/abc"))
{
printf("\n putenv() failed\n");
return 1;
}
printf("\n Successfully Added a new value to existing environment variable MYENVAR\n");
val = getenv("MYENVAR");
printf("\nNew value of environment variable MYENVAR is [%s]\n",val);
return 0;
}
Code:
~/practice $ ./environ Current value of environment variable MYENVAR is [/home/himanshu] Successfully Added a new value to existing environment variable MYENVAR New value of environment variable MYENVAR is [/home/himanshu/abc]
Now, we can also add/change an environment variable with function setenv(). Lets see how :
Code:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
char *val = getenv("MYENVAR");
if(val == NULL)
{
if(setenv("MYENVAR","/home/himanshu",0))
{
printf("\n setenv() failed\n");
return 1;
}
val = getenv("MYENVAR");
}
printf("\nCurrent value of environment variable MYENVAR is [%s]\n",val);
if(setenv("MYENVAR","/home/himanshu/abc",1))
{
printf("\n setenv() failed\n");
return 1;
}
printf("\n Successfuly Added a new value to existing environment variable MYENVAR\n");
val = getenv("MYENVAR");
printf("\nNew value of environment variable MYENVAR is [%s]\n",val);
return 0;
}
Lets see the output :
Code:
~/practice $ ./environ Current value of environment variable MYENVAR is [/home/himanshu] Successfully Added a new value to existing environment variable MYENVAR New value of environment variable MYENVAR is [/home/himanshu/abc]
A point worth noting
Please note that if you set/change an environment variable using the above shown techniques. The persistence of that particular change is temporary. If a new environment variable is added through code, its visibility remains up till the code is running. As soon as the process terminates, the environment variable is cleared.
To make permanent changes put the new environment string at the end of the .profile, or .bash_rc or .bash_profile file, depending on your distribution.
Conclusion
To conclude, this article demonstrates the use of environment variables, how to access them through code. Also, how we can fetch the value or change the value of existing environment variable through C functions.
Stay tuned for more...
