What is an environment
View and change the environment
Manipulating variables
Saving your environment
Miscellaneous
What is an environment?
The environment, in terms of computing on Unix/Linux machines, refers to the settings, options, and configurations you can control to make the machine do what you want it to do. Think of it like the way you arrange your desk or workspace – what items do you always have around? Perhaps a set of pencils, a mug, a picture of your cat? In a similar way, Unix allows you to customize your workspace so that you can easily find the things you need most often.
The way this is done is through shell variables, hidden configuration files, and settings. An environment variable is set in the shell – the program that runs on Linux that listens to you type, and tries its best to aggravate you. It is located at /bin/bash for many systems. The bash shell itself can be configured using hidden files called .bashrc and .bash_profile, which usually hang out in your home directory (file path ~/.bin/bash, ~/.bashrc, or ~/.bash_profile). Variables can be almost anything you want to store to remember or use later; for example, if I wanted to store my favorite pizza topping I could put this in my .bashrc:
export PIZZA_TOPPING="cheese"
If I had a program to order me a pizza, it could now look up my favorite topping:
echo $PIZZA_TOPPING
Variables for the bash are capitalized by convention. You set them with an equals sign ‘=’ and call them with a dollar sign ‘$’. You shouldn’t set a variable by putting a dollar sign in front of it, and bash doesn’t let you have any spaces between the name, the equals sign, and the value. Sometimes you will see curly braces around the variable name to make it clear what is the variable name and what is the rest of the text:
echo "I would like to order a ${PIZZA_TOPPING}y-licious pizza"
Some variable names are already taken by the shell and have special meanings.
How to view and change the environment
If you type env into the command line, you’ll get a whole bunch of info. The most important things you need for installing software are anything with PATH in the name, the CC variable, and the FLAGS. If you haven’t run into the grep command before, no time like now:
env | grep "PATH"
This will show you some of the variables you have set.
Some variables and what they do
Here are some variables you should know and love. Check out the gcc docs for more details.
-
PATH – this should have the locations of programs you want to RUN. Note that to run something using PATH, it has to be executable – ie, the permissions need to have ‘x’.
-
LIBRARY_PATH – use this when you want to add libraries to a program you are trying to COMPILE.
-
LD_LIBRARY_PATH – use this when you want to add libraries to a program you are trying to RUN.
-
CPATH – use this to add header files to a program you are trying to COMPILE.
-
C_INCLUDE_PATH or CPLUS_INCLUDE_PATH – use this to add header files to a program you are trying to RUN.
- PWD – prints the current working directory. You don’t usually set it, but it is handy to have
Manipulating variables
To get the software to work, the shell has to know where the software is, and how to put all of its pieces together. This means paths to executable files, libraries, yada yada. You can add more places for your shell to look by changing environment variables. Be careful when changing these variables – often, order matters, and you might not want to overwrite what’s already there. Most shells allow you to add stuff to the front of a variable, the end of a variable, unset a variable, or totally replace what’s there. For fun, do this:
export PATH=
or:
unset PATH
This illustrates what happens when you blitz a variable. PATH is a pretty critical variable, and your shell experience becomes crippled without it. Logout and log back in, or source your profile again, for example:
source ~/.bashrc
For PATH variables, you can add to the front like so:
export PATH=/some/new/path/to/add:$PATH
The colon acts like a delimiter between entries. Calling the PATH variable again (WITH $) means to add whatever’s already in there to the end. To add to the back:
export PATH=$PATH:/some/new/path/to/add
If you’re using a shell that is not bash, you may have to look up the equivalent operations, but that’s a general idea. If you don’t include the variable itself, you are replacing everything already there with whatever your new text is.
export PATH=/just/this/path/and/no/others
Why do these points matter? When the shell is searching for an executable to run, for example, the ‘less’ executable, it searches the PATH from the front to the back. If it finds anything called less, it runs it. If you create a file, call it less, and make it executable, you can point your PATH at its location and it will execute it. Test it yourself; create a file and name it less:
#!/bin/sh
echo "lol"
Now change your PATH:
$which less
/usr/bin/less
$export PATH=$PWD:$PATH
$chmod a+x less
$which less
~/less
$less
lol
This can be handy when you want to force the shell to only look certain places, or to use, say, python3.6 installed in a special directory instead of python2.7 in /usr/bin. In most cases, you probably want to add special paths to the front of the variable so that your changes take precedence. Note, however, that there are some things you can’t get rid of in this way; the system has defaults that are out of your reach without superpowers. For example, unsetting LD_LIBRARY_PATH does not keep the linker from finding libraries in the system folders like /usr/lib. Another note on variables – they are very particular about when they apply. If you export a variable, it is set for your shell and its children. You can also set a variable for just one command, but its children won’t inherit it. Test this:
$PATH=$PWD:$PATH which less
/usr/bin/less
$PATH=$PWD:$PATH less
lol
Because the path was given to which, and which went looking for less in a subshell, the variable was lost because it was not exported. Even if you export a variable, if the command you use is overridden by alias in your shell, it won’t percolate down. For example, if you create a file called ls:
$ ./ls
lol
$which ls
alias ls=’ls –color=auto’
~/ls # The ls that’s in the current directory (~) was found by PATH
$ls
Documents Music Pictures bin Desktop Downloads
Notice how calling ls has invoked /usr/bin/less and didn’t print “lol”.
Saving your environment
Most of the manipulation we’ve gone over so far – exporting and setting variables – will be wiped out when you logout. To make these changes available every time you login, make sure to put your export statements into your shell’s startup profile! This is usually located in your home directory and will be called .bashrc if bash is your shell. I really recommend saving a copy of your .bashrc file is before making any change to it, and also keep one window logged in while testing another login window in case you make any catastrophic errors. Avoid calling anything in your .bashrc that creates a new shell, because that new shell will source your .bashrc, which will create a new shell – and it’ll hang forever. I made this mistake by adding the newgrp command to my .bashrc!
Notes for folks installing software to be used by others
If you are a control junkie and have lots of fancy things set in your profile, bashrc, or similar shell tweaks, I would recommend you create a function that gives you a clean env – something that matches your user’s or default environment. This will save you from getting something to work for you that relies on your particular environment, and then getting a tragic email later when it doesn’t work for someone else. Even better, keep a completely unprivileged account around for testing so that you can match your user’s experiences.
Now you are versed in variables! Stay tuned to see how the Modules change your environment.