
Linux System Programming Techniques
By :

Another way to communicate with the shell—and to configure a program—is via environment variables. By default, there are a lot of environment variables already set. These variables contain information on just about anything regarding your user and your settings. Some examples include the username, which type of terminal you are using, the path variable we discussed in previous recipes, your preferred editor, your preferred locale and language, and more.
Knowing how to read these variables will make it much easier for you to adapt your programs to the user's environment.
In this recipe, we will write a program that reads environment variables, adapts its output, and prints some information about the user and the session.
For this recipe, we can use just about any shell. Other than a shell, we'll need the GCC compiler.
Follow these steps to write a program that reads environment variables:
env-var.c
. You can also download the whole program from https://github.com/PacktPublishing/Linux-System-Programming-Techniques/blob/master/ch2/env-var.c. This program will read some common environment variables from your shell using the getenv()
function. The strange-looking number sequences (\033[0;31
) are used to color the output:#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { /* Using getenv() to fetch env. variables */ printf("Your username is %s\n", getenv("USER")); printf("Your home directory is %s\n", getenv("HOME")); printf("Your preferred editor is %s\n", getenv("EDITOR")); printf("Your shell is %s\n", getenv("SHELL")); /* Check if the current terminal support colors*/ if ( strstr(getenv("TERM"), "256color") ) { /* Color the output with \033 + colorcode */ printf("\033[0;31mYour \033[0;32mterminal " "\033[0;35msupport " "\033[0;33mcolors\033[0m\n"); } else { printf("Your terminal doesn't support" " colors\n"); } return 0; }
$> gcc env-var.c -o env-var
$> ./env-var Your username is jake Your home directory is /home/jake Your preferred editor is vim Your shell is /bin/bash Your terminal support colors
echo
. Make a note of the $TERM
variable. The dollar sign ($
) tells the shell that we want to print the TERM
variable, not the word TERM:$> echo $USER jake $> echo $HOME /home/jake $> echo $EDITOR vim $> echo $SHELL /bin/bash $> echo $TERM screen-256color
$TERM
variable to a regular xterm
, without color support, we would get a different output from the program:$> export TERM=xterm $> ./env-var Your username is jake Your home directory is /home/jake Your preferred editor is vim Your shell is /bin/bash Your terminal doesn't support colors
$> export TERM=screen-256color
$> echo $TERM xterm-256color $> TERM=xterm ./env-var Your username is jake Your home directory is /home/jake Your preferred editor is vim Your shell is /bin/bash Your terminal doesn't support colors $> echo $TERM xterm-256colo
env
command. The list will probably be several pages long. All of these variables can be accessed using the getenv()
C function:$> env
We use the getenv()
function to get the values from the shell's environment variables. We print these variables to the screen.
Then, at the end of the program, we check if the current terminal has color support. This is usually denoted by something such as xterm-256color
, screen-256color
, and so on. We then use the strstr()
function (from string.h
) to check if the $TERM
variable contains the 256color
substring. If it does, the terminal has color support, and we print a colorized message on the screen. If it doesn't, however, we print that the terminal doesn't have color support, without using any colors.
All of these variables are the shell's environment variables and can be printed with the echo
command; for example, echo $TERM
. We can also set our own environment variables in the shell; for instance, export FULLNAME=Jack-Benny
. Likewise, we can change existing ones by overwriting them, just as we did with the $TERM
variable. We can also override them by setting them at runtime, like we did with TERM=xterm ./env-var
.
Regular variables set with the FULLNAME=Jack-Benny
syntax are only available to the current shell and are hence called local variables. When we set variables using the export
command, they become global variables or environment variables, a more common name, available to both subshells and child processes.
There's more…
We can also change environment variables and create new ones in a C program by using the setenv()
function. However, when we do so, those variables won't be available in the shell that started the program. The program we run is a child process of the shell, and hence it can't change the shell's variable; that is, its parent process. But any other programs started from inside our own program will be able to see those variables. We will discuss parent and child processes in more depth later in this book.
Here is a short example of how to use setenv()
. The 1
in the third argument to setenv()
means that we want to overwrite the variable if it already exists. If we change it to a 0
, it prevents overwriting:
env-var-set.c
#define _POSIX_C_SOURCE 200112L #include <stdio.h> #include <stdlib.h> int main(void) { setenv("FULLNAME", "Jack-Benny", 1); printf("Your full name is %s\n", getenv("FULLNAME")); return 0; }
If we compile and run the program and then try to read $FULLNAME
from the shell, we'll notice that it doesn't exist:
$> gcc env-var-set.c -o env-var-set $> ./env-var-set Your full name is Jack-Benny $> echo $FULLNAME