Introduction
When interacting with the server through a shell session, there is a lot of information compiled by the shell to determine its behavior and access to resources. Some of these settings are included in the configuration settings, while others are determined by user input.
One way the Shell tracks all these settings and details is through an area called the environment that it maintains. An environment is an area built by the shell each time it starts a session, containing variables that define system properties.
In this guide, we will discuss how to interact with the environment and read or set environment and shell variables through configuration files and interactively.
If you want to follow the action on your local system or remote server, open a terminal and run the commands from this tutorial there.
How environment and environment variables work
Each time a shell session is generated, a process is performed to collect and compile information that should be available to the shell process and its child processes. It gets data for these settings from various different files and settings of the system.
The environment provides a medium through which the shell process can obtain or set settings and pass these to its child processes.
The environment is implemented as a string representing key-value pairs. If multiple values are passed, they are usually made by a colon (:
) character separation. Each pair usually looks like this:
KEY=value1:value2:...
If the value contains important spaces, use quotes:
KEY="Value with space"
The keys in these cases are variables. They can be one of environment variables or shell variables.
Environment variablesis a variable defined for the current shell and will be inherited by any child shell or process. Environment variables are used to pass information to processes generated from the shell.
Shell variablesAre variables that are only included in the shell that sets or defines them. They are often used to track ephemeral data, such as the current working directory.
By convention, these types of variables are usually defined in all capital letters. This helps users distinguish environment variables in other contexts.
Print shell and environment variables
Each shell session tracks its own shell and environment variables. We can access these variables in several different ways.
We can useenv
orprintenv
Commands view a list of all environment variables. By default they should be exactly the same:
printenv
Your shell environment may have more or fewer variables set and have different values as follows:
SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv
This isprintenv
andenv
The output is quite typical. The difference between these two commands will only appear in their more specific functions. For example, useprintenv
, you can request the value of a single variable:
printenv PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
on the other hand,env
Allows you to modify the environment in which the program runs by passing a set of variable definitions to the command:
env VAR1="value" command_to_run command_options
Since, as we learned above, child processes usually inherit the parent process's environment variables, this gives you the opportunity to overwrite the value or add extra variables to the child process.
As can be seen from the output of our printenv command, the system files and processes have set up quite a few environment variables without our input.
These show environment variables, but how do we view shell variables?
The set command can be used for this purpose. If we enter set without any extra parameters, we will get a list of all shell variables, environment variables, local variables, and shell functions:
set
BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .
This is usually a huge list. You may want to transfer it into a paging program to handle the number of outputs more easily:
set | less
The amount of extra information we received was a bit overwhelming. We may not need to know all defined bash functions, for example.
We can specifyset
It should be run in POSIX mode to clean the output so that the shell function will not be printed. We can do this in the child shell so that the current environment is not changed:
(set -o posix; set)
This lists all defined environments and shell variables.
We can try to use this output withenv
orprintenv
The output of the command is compared to try to get a list of shell-only variables, but this will be imperfect because of the different ways these commands output information:
comm -23 <(set -o posix; set | sort) <(env | sort)
Since the set command outputs quoted values, while the printenv and env commands do not quote the values of the string, this may still include some environment variables.
This should still give you a good concept about environments and shell variables set in your session.
These variables are used for various things. They provide an alternative way to set persistent values between processes without writing changes to a file.
Common environment variables and shell variables
Some environment variables and shell variables are very useful and are often cited
-
SHELL
: Describes the shell that will explain any commands you entered. In most cases, it will be bash by default, but if you prefer other options, you can set other values as well. -
TERM
: Specify the type of terminal to simulate when running the shell. Different hardware terminals can simulate different operating requirements. Normally, you don't need to worry about this. -
USER
: The currently logged in user. -
PWD
: Current working directory. -
OLDPWD
: Previous working directory. This is reserved by the shell to runcd -
Switch back to the previous directory. -
LS_COLORS
: Define to optionallyls
Command adds color code for color output. This is used to distinguish different file types and provide users with more information in a glance. -
MAIL
: The path to the current user's mailbox. -
PATH
: The list of directories that the system will check when looking for commands. When the user enters a command, the system will check the directory where the executable file is located in this order. -
LANG
: Current language and localization settings, including character encoding. -
HOME
: The home directory of the current user. -
_
: The most recent command executed.
In addition to these environment variables, you often see some shell variables, such as:
-
BASHOPTS
: List of options used when executing bash. This is useful for finding if the shell environment works the way you want it to. -
BASH_VERSION
: A bash version displayed in human-readable form. -
BASH_VERSINFO
: The bash version displayed in machine-readable output. -
COLUMNS
: The number of columns used when drawing the output on the screen. -
DIRSTACK
: usepushd
andpopd
The directory stack available to the command. -
HISTFILESIZE
: The number of command history lines stored in the file. -
HISTSIZE
: The number of lines allowed in memory for command history. -
HOSTNAME
: The host name of the computer at this time. -
IFS
: The internal field separator used to delimit input on the command line. By default, it is a space. -
PS1
: Main command prompt definition. This is used to define the appearance of prompts when you start a shell session.PS2
Used to declare minor prompts when commands span multiple lines. -
SHELLOPTS
: Can be usedset
Shell options set by options. -
UID
: The UID of the current user.
Setting Shell and Environment Variables
use. Here are some common environment variables you will encounter:
To better understand the difference between shell and environment variables and to introduce the syntax for setting these variables, we will do a small demonstration.
Create Shell variables
We will start by defining a shell variable in the current session. This is easy to implement; we only need to specify a name and a value. We will follow the convention that the variable name is fully capitalized and set it to a simple string.
TEST_VAR='Hello World!'
Here we use quotes because the value of the variable contains spaces. Additionally, we use single quotes because the exclamation mark is a special character in the bash shell, which is usually extended to bash history if not escaped or put into single quotes.
Now we have a shell variable. This variable is available in the current session but is not passed to the child process.
We can verify this by looking for our new variable in the set output:
set | grep TEST_VAR
TEST_VAR='Hello World!'
We can tryprintenv
To verify that this is not an environment variable:
printenv | grep TEST_VAR
No output should be returned.
Let's take advantage of this opportunity to demonstrate a way to access the values of any shell or environment variable.
echo $TEST_VAR
Hello World!
As you can see, by prefixing the variable$
Symbols refer to the value of a variable. The shell replaces the value of the variable when it encounters this symbol.
Now we have a shell variable. It should not be passed to any child process. We can generate a new bash shell from the current shell to demonstrate:
bash echo $TEST_VAR
If we enterbash
Generate a child shell and then try to access the content of the variable, nothing will be returned. This is the result we expected.
By enteringexit
Return to our original shell:
exit
Create environment variables
Now, let's convert our shell variable to environment variables. We can do this by exporting variables. The corresponding command is:
export TEST_VAR
This will turn our variable into an environment variable. We can verify this by checking our environment list again:
printenv | grep TEST_VAR
TEST_VAR=Hello World!
This time, our variables are displayed. Let's try again to experiment in our subshell:
bash echo $TEST_VAR
Hello World!
marvelous! Our child shell has received variables set by its parent. Before we exit this child shell, let's try to export another variable. We can set environment variables in one step like this:
export NEW_VAR="Testing export"
Test whether it is exported as an environment variable:
printenv | grep NEW_VAR
NEW_VAR=Testing export
Now, let's exit back to our original shell:
exit
Let's see if our new variable is available:
echo $NEW_VAR
Nothing was returned.
This is because environment variables are only passed to the child process. There is no built-in method to set the parent shell's environment variables. In most cases, this is good and can prevent programs from affecting the operating environment in which they are called.
The NEW_VAR variable is set as an environment variable in our child shell. This variable will be available to itself and to any of its children shells and processes. When we exit back to our main shell, the environment is destroyed.
Degrading and canceling variables
We still define our TEST_VAR variable as an environment variable. We can change it back to shell variable by typing the following command:
export -n TEST_VAR
It is no longer an environment variable:
printenv | grep TEST_VAR
But it's still a shell variable:
set | grep TEST_VAR
TEST_VAR='Hello World!'
If we want to completely cancel a variable, whether it is a shell or an environment variable, we can useunset
Order:
unset TEST_VAR
We can verify that it has been cancelled:
echo $TEST_VAR
Nothing is returned because the variable has been cancelled.
Set environment variables when logging in
We have mentioned the specific details of how many programs use environment variables to decide how to operate. We don't want to set important variables every time we start a new shell session, and we've seen many variables already set when logging in, so how do we automatically create and define variables?
In fact, this is a more complex issue than it seems at first, because the bash shell reads many configuration files based on how it starts.
Differences between login, non-login, interactive and non-interactive shell sessions
The bash shell reads different configuration files according to the start of the session.
One difference between different sessions is whether the shell acts asLog inorNon-loginSession generation.
Log inA shell is a shell session that starts by authenticating the user. If you log in and authenticate through a terminal session or SSH, your shell session will be set to log in to the shell.
If you start a new shell session in an already authenticated session, it's like we call it through the terminalbash
Like the command, aNon-loginshell session. When launching the shell, you are not asked to enter authentication details.
Another thing that can be distinguished is whether the shell session is interactive or non-interactive.
InteractiveA shell session is a shell session connected to the terminal.Non-interactiveThe shell session is not connected to the terminal session.
Therefore, each shell session is classified as logged in or non-login, interactive or non-interactive.
The session started as a login session will first be from/etc/profile
File reading configuration details. It will then look for the first login shell configuration file in the user's home directory to get user-specific configuration details.
It will read~/.bash_profile
、~/.bash_login
and~/.profile
The first file found in and no other file will be read.
Instead, the session defined as a non-login shell will be from/etc/
Start reading, and then read user-specific~/.bashrc
Files to build its environment.
A non-interactive shell will read the name asBASH_ENV
environment variable and read the specified file to define the new environment.
Implement environment variables
As you can see, usually we need to look at various different files to set our environment variables.
This provides a lot of flexibility and can help set some settings in the login shell in certain situations, as well as others in non-login shells. However, most of the time, we want to set the same settings in both cases.
Fortunately, most Linux distributions are configured with login configuration files derived from non-login configuration files. This means that you can define environment variables in a non-login configuration file that you want to exist in both cases. These variables will then be read in both cases.
Usually we set user-specific environment variables and we usually want our settings to be available in both login and non-login shells. This means that the place where these variables are defined is~/.bashrc
in the file.
Now open this file:
nano ~/.bashrc
This is likely to have quite a lot of data already included. Most of the definitions here are used to set bash options, regardless of environment variables. You can set environment variables like you would on the command line:
export VARNAME=value
Any new environment variable can be added to~/.bashrc
anywhere in the file, as long as they are not placed in the middle of another command or for loop. Then save and close the file. The next time the shell session is started, your environment variable declaration will be read and passed to the shell environment. You can force the current session to read the file immediately by typing the following command:
source ~/.bashrc
If you need to set system-wide variables, you may want to consider adding them to /etc/profile, /etc/ or /etc/environment.
in conclusion
Environment variables and shell variables are always present in your shell session, which is very useful. They are an interesting way for the parent process to set configuration details for its child process, and one way to set options outside of the file.
In certain situations, this has many advantages. For example, some deployment mechanisms rely on environment variables to configure authentication information. This is useful because it does not require that this information be saved in a file that may be seen by outsiders.
There are many other more common but more common situations where you will need to read or change the system's environment. These tools and techniques should provide you with a good foundation in order to make these changes and use them correctly.
The above is the detailed content of the tutorial on reading or setting environments and shell variables on Linux. For more information about setting environments and shell variables in Linux, please pay attention to my other related articles!