M. Garrels. Bash Guide. Variables. How to set and disable local, user and system environment variables in Linux How to find where a shell variable is written

Variable types

As you can see from the examples above, shell variables are usually written in capital letters. Bash stores lists of variables of two types:

Global Variables

Global or environment variables are available in all shells. To show environment variables, you can use the commands env or printenv. These commands are provided as part of the package sh-utils.

Below is a typical output:

Franky ~> printenv CC=gcc CDPATH=.:~:/usr/local:/usr:/ CFLAGS=-O2 -fomit-frame-pointer COLORTERM=gnome-terminal CXXFLAGS=-O2 -fomit-frame-pointer DISPLAY=: 0 DOMAIN=hq.garrels.be e= TOR=vi FCEDIT=vi FIGNORE=.o:~ G_BROKEN_FILENAMES=1 GDK_USE_XFT=1 GDMSESSION=Default GNOME_DESKTOP_SESSION_ID=Default GTK_RC_FILES=/etc/gtk/gtkrc:/nethome/franky/.gtkrc -1.2-gnome2 GWMCOLOR=darkgreen GWMTERM=xterm HISTFILESIZE=5000 history_control=ignoredups HISTSIZE=2000 HOME=/nethome/franky HOSTNAME=octarine.hq.garrels.be INPUTRC=/etc/inputrc IRCNAME=franky JAVA_HOME=/usr/java/ j2sdk1.4.0 LANG=en_US LDFLAGS=-s LD_LIBRARY_PATH=/usr/lib/mozilla:/usr/lib/mozilla/plugins LESSCHARSET=latin1 LESS=-edfMQ LESSOPEN=|/usr/bin/lesspipe.sh %s LEX=flex LOCAL_MACHINE=octarine LOGNAME=franky LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd= 40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*. com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz= 01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01; 31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31: *.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*. tif=01;35: MACHINES=octarine MAILCHECK=60 MAIL=/var/mail/franky MANPATH=/usr/man:/usr/share/man/:/usr/local/man:/usr/X11R6/man MEAN_MACHINES= octarine MOZ_DIST_BIN=/usr/lib/mozilla MOZILLA_FIVE_HOME=/usr/lib/mozilla MOZ_PROGRAM=/usr/lib/mozilla/mozilla-bin MTOOLS_FAT_COMPATIBILITY=1 MYMALLOC=0 NNTPPORT=119 NNTPSERVER=news NPX_PLUGIN_PATH=/plugin/ns 4plugin/:/ usr/lib/netscape/plugins OLDPWD=/nethome/franky OS=Linux PAGER=less PATH=/nethome/franky/bin.Linux:/nethome/franky/bin:/usr/local/bin:/usr/local/sbin :/usr/X11R6/bin:/usr/bin:/usr/sbin:/bin:/sbin:. PS1=\[\033franky is in \w\[\033 PS2=More input> PWD=/nethome/franky SESSION_MANAGER=local/octarine.hq.garrels.be:/tmp/.ICE-unix/22106 SHELL=/bin /bash SHELL_LOGIN=--login SHLVL=2 SSH_AGENT_PID=22161 SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass SSH_AUTH_SOCK=/tmp/ssh-XXmhQ4fC/agent.22106 START_WM=twm TERM=xterm TYPE=type USERNAME= franky USER=franky _=/usr/bin/printenv VISUAL=vi WINDOWID=20971661 XAPPLRESDIR=/nethome/franky/app-defaults XAUTHORITY=/nethome/franky/.Xauthority XENVIRONMENT=/nethome/franky/.Xdefaults XFILESEARCHPATH=/usr /X11R6/lib/X11/%L/%T/%N%C%S:/usr/X11R6/lib/X11/%l/%T/%N%C%S:/usr/X11R6/lib/X11 /%T/%N%C%S:/usr/X11R6/lib/X11/%L/%T/%N%S:/usr/X11R6/lib/X11/%l/%T/%N%S :/usr/X11R6/lib/X11/%T/%N%S XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB XMODIFIERS=@im=none XTERMID= XWINHOME=/usr/X11R6 X=X11R6 YACC=bison - y

Local variables

Local variables are only available in the current command shell. If the builtin command set is used without any parameters, it will return a list of all variables (including runtime variables) and functions. Let's use formatting and produce a sorted result that takes into account the locality of the variables.

Below is the diff file created by comparing the results of the commands printenv And set, after removing from the list of functions that are also displayed by the command set:

Franky ~> diff set.sorted printenv.sorted | grep "<" | awk "{ print $2 }" BASE=/nethome/franky/.Shell/hq.garrels.be/octarine.aliases BASH=/bin/bash BASH_VERSINFO=(="2" BASH_VERSION="2.05b.0(1)-release" COLUMNS=80 DIRSTACK=() DO_FORTUNE= EUID=504 GROUPS=() HERE=/home/franky HISTFILE=/nethome/franky/.bash_history HOSTTYPE=i686 IFS=$" LINES=24 MACHTYPE=i686-pc-linux-gnu OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PIPESTATUS=(="0") PPID=10099 PS4="+ PWD_REAL="pwd SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor THERE=/home/franky UID=504

Dividing variables by their contents

Apart from dividing variables into local and global, we can also divide them into categories based on what content is stored in the variable. In this regard, variables are divided into four types:

  • String variables
  • Integer variables
  • Variables - constants
  • Variables - arrays

We'll discuss these types of variables in Chapter 10. Now we will use integer and string values ​​in our variables.

Creating Variables

In variables, uppercase and lowercase characters are distinguished and uppercase characters are used by default. Sometimes it is customary to use lowercase characters to write local variables. However, you can use any characters for variable names and even mix upper and lower case characters. You can also use numbers in variable names, but names starting with numbers are not allowed:

Prompt> export 1number=1 bash: export: `1number=1": not a valid identifier

To set a variable in the command shell, use the following command

VARNAME="value"

Do not insert spaces around the equal sign; this will cause errors. When you assign values ​​to variables, it is a good habit to enclose the contents of the string in quotes; this reduces the chance that you will make a mistake.

Some examples of using upper and lower case, numbers and spaces (the command not found message indicates there is a problem - approx.):

Franky ~> MYVAR1="2" franky ~> echo $MYVAR1 2 franky ~> first_name="Franky" franky ~> echo $first_name Franky franky ~> full_name="Franky M. Singh" franky ~> echo $full_name Franky M. Singh franky ~> MYVAR-2="2" bash: MYVAR-2=2: command not found franky ~> MYVAR1 ="2" bash: MYVAR1: command not found franky ~> MYVAR1= "2" bash: 2: command not found franky ~> unset MYVAR1 first_name full_name franky ~> echo $MYVAR1 $first_name $full_name<--no output-->franky ~>

Export variables

A variable created as shown in the example above is only available in the current command shell. This is a local variable: child processes of the current shell will not be aware of this variable. In order to pass variables to a subshell, we need export it using the builtin command export. The variables that are exported are called environment variables. Assigning a value and exporting is usually done in one step:

Export VARNAME="value"

A subshell can change variables that are inherited from the parent process, but changes made by the child process do not affect the parent process. This is demonstrated in the following example:

Franky ~> full_name="Franky M. Singh" franky ~> bash franky ~> echo $full_name franky ~> exit franky ~> export full_name franky ~> bash franky ~> echo $full_name Franky M. Singh franky ~> export full_name= "Charles the Great" franky ~> echo $full_name Charles the Great franky ~> exit franky ~> echo $full_name Franky M. Singh franky ~>

The first time a subshell attempts to read the value of full_name , the value is not set (command echo shows an empty line). After the subshell is exited, the variable full_name is exported to the parent shell - the variable can be exported after it has been assigned a value. A new subshell is then started, displaying the variable exported from the parent shell. The variable is modified and a different value will be stored in it, but in the parent shell the value of this variable remains the same.

Reserved Variables

Bourne Reserved Shell Variables

Bash uses certain shell variables just like the Bourne shell. In some cases, Bash assigns a variable its default value. The table below shows short description these simple shell variables:

Table 3.1. Bourne Reserved Shell Variables

Variable name Definition

List of directories, separated by colons, used when searching for a path using the builtin command CD.

Home directory current user; used by default in builtin command CD. The value of this variable is also used instead of the tilde character.

List of characters used to separate fields; used when the shell, after performing all the substitutions, splits the result into individual words.

If this parameter is set to a filename and MAILPATH is not set, Bash will inform the user that mail has been received in the specified file.

A colon-separated list of file names that the command shell periodically checks for new mail.

The value of the last argument in the parameter processed by the builtin command getopts.

Index of the last parameter argument processed by the builtin command getopts.

A colon-separated list of directories in which the shell looks for commands.

Primary prompt line. The default value is ""\s-\v\$ "".

Secondary prompt line. The default value is ""> "".

Bash Reserved Variables

The values ​​of these variables are set or used in Bash, but they are not generally treated as special in other shells.

Table 3.2. Bash Reserved Variables

Variable name Definition

This variable controls how the shell interacts with the user and performs tasks.

Full path used to start the current Bash instance.

If this variable is set at the time Bash is invoked to execute the script, its value is used as the name of the startup file that must be read before the script is executed.

The version number of the current instance of Bash.

Variable is a read-only array whose array elements store version information of this instance Bash.

When printing selected lists, the built-in command is used select to determine the width of the terminal. Automatically set when receiving signal SIGWINCH.

A pointer in $(COMP_WORDS) to the word that stores the current cursor position.

Current command line.

A pointer to the current cursor position relative to the start of the current command.

Variable is an array consisting of individual words used on the current command line.

Variable is an array from which Bash reads possible options string completions generated by a shell function called by a service designed to program completions

The variable is an array that stores the current state of the directory stack.

Numeric effective user ID The ID of the current user.

The default editor used when in a built-in command fc the -e parameter is specified

A colon-separated list of suffixes that should be ignored when performing automatic filename completion.

The name of the shell function currently running.

A colon-separated list of patterns that define a set of filenames to be ignored when replacing filenames.

The variable is an array containing a list of groups to which the current user belongs.

Up to three characters that control command history substitution, quick substitution, and splitting of completed substitutions into tokens.

The number of the current command in the command history or its index in the command history list.

Determines whether the command will be added to the command history file.

The name of the file in which the command history is saved. Default value: ~/.bash_history.

The default maximum number of lines contained in a command history file is 500.

A colon-separated list of patterns that determine whether a command should be saved to command history lists.

The default maximum number of commands that can be stored in the command history list is 500.

Contains a filename in the same format as the /etc/hosts file, which can be read when the command shell needs to complete the hostname.

Current host name.

A string describing the machine on which Bash is running.

Controls what the shell does when it receives a character as the terminating character of an input stream EOF(end of file symbol).

The name of the Readline program initialization file that replaces the default /etc/inputrc file.

Used to define the locale category for all categories not explicitly specified by variables whose names begin with the characters LC_ .

This variable overrides the value of the LANG variable and all other variables that begin with the LC_ characters that specify the localization category.

This variable specifies the sort order used when sorting pattern-matched filenames, and determines the interpretation of ranges, match classes, and character comparison rules for filename substitution and pattern matching.

This variable determines how characters are interpreted and whether they belong to a particular class for filename expansion and pattern matching.

This variable specifies the localization category used to process strings in double quotes, preceded by the $ symbol.

This variable specifies the localization category for the number format.

The line number in the script or shell function that is currently executing.

Used by builtin command select to determine the length of the column in which the selected lists are displayed.

A string that fully describes the type of system on which Bash is running, using the standard GNU CPU-COMPANY-SYSTEM format.

Specifies, in seconds, how often the shell should check for mail in files specified in the MAILPATH or MAIL variables.

Previous working directory set using builtin command CD.

If set to 1, Bash displays error messages generated by the builtin command getopts.

String describing operating system, which runs Bash.

The variable is an array containing a list of process exit state values ​​in the last pipeline (which can consist of a single command).

If this variable is added to the environment when bash is started, the shell goes into POSIX mode.

If this variable is set, the value is interpreted as a command that is executed before each primary prompt line (PS1) is issued.

The value of this variable is used for the command select as a prompt string. Default - ""#? ""

The value of the prompt string that is issued before the command line when the -x option is set to enable echoing command line; the default is ""+ "".

Current working directory set by builtin command CD.

Each time this parameter is accessed, a random integer is generated in the range from 0 to 32767. The value of this variable is used in random number generators.

Default variable in builtin command read.

This variable indicates the number of seconds that have passed since the command shell was launched.

List of parameters set in the command shell; separated by colons.

Increments by one each time a new instance of Bash is started.

The value of this parameter is used as a string that specifies the format for issuing runtime information for pipelines that are preceded by a reserved word time.

If the TMOUT variable is set to a value greater than zero, then it is treated as the default timeout in the builtin command read. When a command shell is started in interactive mode, this value is interpreted as the number of seconds that the shell will wait for input after issuing the initial prompt line. If no input is received, then after this time Bash exits.

Numeric value, real user ID for the current user.

See the Bash man pages or documentation for more information. Some variables are read-only, some are automatically set, and some become meaningless when they are set to something other than their default value.

Special parameters

The command shell treats some parameters in a special way. These parameters can only be used to obtain values ​​from them; they cannot be assigned values.

Table 3.3. Bash special variables

Symbol Definition

Returns positional parameters starting from the first one. When a parameter is specified in double quotes, it is replaced by a single word containing the values ​​of each parameter, separated by the first character of the IFS special variable.

Returns positional parameters starting from the first one. When a parameter is specified in double quotes, each parameter is returned as a separate word.

Returns the number of positional parameters specified as a decimal value.

Returns the return code of the last pipeline executed in foreground mode.

The hyphen parameter returns the flags of the current parameter as they were set when the builtin command was called set, or as they were set by the shell itself (for example, -i).

Returns the shell process ID.

Returns the process ID of the last command executed in the background (asynchronous) mode.

Returns the name of the shell or script.

The value of the "underscore" parameter is set when the command shell is started and contains full name shell or script that is executed as it was passed in the argument list. The value will then be replaced by the last argument of the previous command. This parameter also specifies the full path to each command executed and placed in the environment that was exported to that command. When mail is checked, this parameter contains the name of the mail file.

Positional parameters are the words following the name of the shell script. They are stored in the variables $1, $2, $3 and so on. Variables are added to the internal array as needed. The $# variable specifies the total number of parameters, as demonstrated in the following simple script:

# positional.sh # This script reads 3 positional parameters and prints them out. POSPAR1="$1" POSPAR2="$2" POSPAR3="$3" echo "$1 is the first positional parameter, \$1." echo "$2 is the second positional parameter, \$2." echo "$3 is the third positional parameter, \$3." echo echo "The total number of positional parameters is $#."

When running the script, you can specify any number of arguments:

Franky ~> positional.sh one two three four five one is the first positional parameter, $1. two is the second positional parameter, $2. three is the third positional parameter, $3. The total number of positional parameters is 5. franky ~> positional.sh one two one is the first positional parameter, $1. two is the second positional parameter, $2. is the third positional parameter, $3. The total number of positional parameters is 2.

For more information on using these parameters, see Chapter 7, Conditional Statements, and the section on the shift built-in command.

Some examples of other special parameters:

Franky ~> grep dictionary /usr/share/dict/words dictionary franky ~> echo $_ /usr/share/dict/words franky ~> echo $$ 10662 franky ~> mozilla & 11064 franky ~> echo $! 11064 franky ~> echo $0 bash franky ~> echo $? 0 franky ~> ls doesnotexist ls: doesnotexist: No such file or directory franky ~> echo $? 1 franky ~>

User franky starts by entering the command grep, which assigns the value to the variable _ . The process ID of this shell is 10662. If the execution of some job is transferred to background mode, in a variable! there will be a process identifier background job. A working command shell is bash. If an error was made, in the variable? there will be a return code different from 0 (zero).

Expanding the scope of application of scripts that have variables

In addition to making your script more readable, variables can also help you quickly use your script in other contexts or for other purposes. Consider the following example - a very simple script that does on a remote server backup copy user's home directory franky:

#!/bin/bash # This script makes a backup of my home directory. cd /home # This creates the archive tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1 # First remove the old bzip2 file. Redirect errors because this generates some if the archive # does not exist. Then create a new compressed file. rm /var/tmp/home_franky.tar.bz2 2> /dev/null bzip2 /var/tmp/home_franky.tar # Copy the file to another host - we have ssh keys for making this work without intervention. scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1 # Create a timestamp in a logfile. date >> /home/franky/log/home_backup.log echo backup succeeded >> /home/franky/log/home_backup.log

First of all, you are more likely to make mistakes if you manually specify files and directories every time you need them. Secondly, suppose the user franky wants to pass this script to the user Carol, then before Carol will be able to use the script for Reserve copy his home directory, he will have to edit quite a bit. The same thing will happen if the user franky will want to use this script to backup other directories. To expand the scope, use variables for all files, directories, usernames, server names, etc. Then you only need to change the value once and not have to go through the entire script to find all the places where a particular parameter occurs. Example:

#!/bin/bash # This script makes a backup of my home directory. # Change the values ​​of the variables to make the script work for you: BACKUPDIR=/home BACKUPFILES=franky TARFILE=/var/tmp/home_franky.tar BZIPFILE=/var/tmp/home_franky.tar.bz2 SERVER=bordeaux REMOTEDIR=/ opt/backup/franky LOGFILE=/home/franky/log/home_backup.log cd $BACKUPDIR # This creates the archive tar cf $TARFILE $BACKUPFILES > /dev/null 2>&1 # First remove the old bzip2 file. Redirect errors because this generates some if the archive # does not exist. Then create a new compressed file. rm $BZIPFILE 2> /dev/null bzip2 $TARFILE # Copy the file to another host - we have ssh keys for making this work without intervention. scp $BZIPFILE $SERVER:$REMOTEDIR > /dev/null 2>&1 # Create a timestamp in a logfile. date >> $LOGFILE echo backup succeeded >> $LOGFILE

While working with the server, the shell compiles a large amount of information that determines its behavior and access to resources. Some of these options are found in shell settings, others are determined by user input.

One way for the shell to track this information is through the environment. The environment is an area containing system-defining variables that the shell builds each time a session is started.

This tutorial explains how to interact with the environment and read or set environment and shell variables interactively and using configuration files. All actions are performed on Ubuntu 12.04 VPS, but any modern Linux distribution should work the same way.

How the environment and its variables work

Each time a shell session is activated, a process is started to collect and compile information that should be available to the shell and its child processes. The shell gets this data from many different files and settings on the system.

In general, the environment provides a transmission facility that collects and sets the necessary settings to the shell process, which in turn passes them on to its child processes.

The environment takes the form of a string containing key-value pairs. Multiple values ​​are typically separated by a colon (:). Each pair generally looks something like this:

KEY=value1:value2:...

If the value contains spaces, you need to use double quotes:

KEY="value with spaces"

In this case, a key means variables of one of two existing species: environment or shell variables.

Environment Variables are variables that have been defined for the current shell and are inherited by all child shells or processes. Environment variables are used to pass information to processes launched from the shell.

Shell Variables are variables that are contained exclusively in the shell in which they were set or defined. They are often used to keep track of current data (for example, the current working directory).

Typically, such variables are denoted using capital letters. This helps users distinguish between environment variables in other contexts.

Printing shell and environment variables

Each session keeps track of its own shell and environment variables. There are several ways to get them out.

To see a list of all environment variables, use the env or printenv commands. By default they will output exactly the same result:

printenv
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 is a typical example of the output of the printenv and env commands. These commands differ only in a few individual functions. For example, printenv can query the values ​​of individual variables:

printenv SHELL
/bin/bash

The env command allows you to change the environment in which programs run by passing a set of variable definitions to the command, something like this:

env VAR1="blahblah" command_to_run command_options

As stated above, child processes typically inherit the environment variables of the parent process, which makes it possible to change values ​​or introduce additional variables for child processes.

As you can see in the output of the printenv command, many environment variables are created using system files and processes without user intervention.

But how do you view shell variables?

To do this, use the set command. When entered without additional parameters, set lists 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=()
. . .

As a rule, this list is quite long. To display it in a more convenient format, open it using a pager program:

This list contains a huge number additional information, which is in this moment not needed (for example, some bash functions).

To "clean up" the output, you need to run the set command in POSIX mode, which bypasses shell functions. This needs to be done in a subshell so as not to change the current environment:

(set -o posix; set)

This action will display all environment and shell variables.

You can also compare this output with the output of the env/printenv commands and try to list only the shell variables, but such a list will not be ideal because the output of these commands is different:

comm -23<(set -o posix; set | sort) <(env | sort)

The list will likely contain multiple environment variables because the set command prints values ​​in quotes, but the printenv and env commands do not.

However, this is a great way to view the environment and shell variables set in a given session.

Such variables are used for all sorts of purposes. They provide an alternative way to set persistent values ​​for a session between processes, eliminating the need to make changes to the file.

Basic environment and shell variables

Some particularly useful environment and shell variables are used very often.

Below is a list of the main environment variables:

  • SHELL: Describes the shell that interprets entered commands. In most cases, bash is installed by default, but this value can be changed if necessary.
  • TERM: Specifies the type of terminal emulated when the shell is launched. Depending on the operational requirements, different hardware terminals can be emulated. Typically you don't need to worry about this.
  • USER: current user.
  • P.W.D.: current working directory.
  • OLDPWD: previous working directory. The shell stores it in case the cd - command is run.
  • LS_COLORS: Defines the color codes that are used to colorize the output of the ls command. This output helps the user read the command result faster (for example, quickly distinguish between file types).
  • MAIL: Path to the user's current mailbox.
  • PATH: A list of directories that the system accesses when executing commands. When the user runs the command, the system checks these directories in the specified order for the executable file.
  • LANG: Current language and localization settings, including character encoding.
  • HOME: The current user's home directory.
  • _ : Last command executed.

After reviewing the list of environment variables, examine the list of shell variables:

  • BASHOPTS: List of options used when executing bash. This can be used to check if the environment is working as expected.
  • BASH_VERSION: The running version of bash in human-readable form.
  • BASH_VERSINFO: A machine-readable version of bash.
  • COLUMNS: Specifies the width of the output in columns.
  • DIRSTACK: A stack of directories accessible to the pushd and popd commands.
  • HISTFILESIZE: The maximum number of lines contained in the command history file.
  • HISTSIZE: The number of commands to be remembered in the history list.
  • HOSTNAME: Current hostname.
  • IFS: Internal input field separator on the command line. The default is space.
  • PS1: Defines the initial prompt line - the type of command line when starting a shell session. The PS2 variable sets the secondary prompt line if the command spans multiple lines.
  • SHELLOPTS: Shell options that can be set using set.
  • UID: Unique identifier for the current user.

Setting shell and environment variables

Below are a few examples to demonstrate the difference between shell and environment variables and to explain the syntax for setting these variables.

Creating Shell Variables

First you need to set the shell variables for the current session. This is done very simply, all you need to do is specify a name and value. As already mentioned, capital letters are used to write the names of such variables.

TEST_VAR="Hello World!"

This example uses quotes because the value contains spaces. Moreover, you need to use single quotes here because the exclamation mark is a special character in the bash shell that accesses command history unless it is escaped or enclosed in single quotes.

So, the resulting shell variable is valid in the current session, but is not passed on to its child processes.

To verify this, use the grep command on the result of the set command:

set | grep TEST_VAR
TEST_VAR="Hello World!"

You can also make sure that this variable is not an environment variable by running grep on the result of the printenv command:

printenv | grep TEST_VAR

This action will not produce any result.

This can be used to expose the value of any shell or environment variable.

echo $TEST_VAR
Hello World!

As you can see, to access the value of a variable, you need to use the $ symbol.

Again, the resulting variable should not be passed to any child process. To test this, inside your current shell, deploy a new bash shell:

bash
echo $TEST_VAR

If you expand the child shell and try to open the contents of the variable, nothing will be printed. This means everything is working properly.

To return to your original shell, type exit:

Creating Environment Variables

Now try turning the shell variable into an environment variable. This is done by exporting the variable. The command that performs the export is named accordingly.

This command turns a shell variable into an environment variable. To check if everything was done correctly, you can look at the list of environment variables again:

printenv | grep TEST_VAR
TEST_VAR=Hello World!

Now this variable is displayed in this list. You can also expand the child shell again:

bash
echo $TEST_VAR
Hello World!

Great! The child shell received a variable from the original shell. Try exporting one more variable before leaving the child shell.

export NEW_VAR="Testing export"

Check if the variable has been exported:

printenv | grep NEW_VAR
NEW_VAR=Testing export

Now return to your original shell:

Check if this variable can be opened:

The result is not returned

This happens because environment variables are only passed to child processes. There is no built-in way to set the parent shell's environment variables. In most cases, this prevents programs from interfering with the operating environment from which they were launched.

The NEW_VAR variable has been set as a child shell environment variable. This variable is valid for this shell and its child shells and processes. After the user returned to the original shell, this environment was destroyed.

Moving and resetting variables

The TEST_VAR variable is still an environment variable. To make it a shell variable again, type:

export -n TEST_VAR

Now this variable is no longer an environment variable:

printenv | grep TEST_VAR

This is a shell variable again:

set | grep TEST_VAR
TEST_VAR="Hello World!"

To completely reset a variable, be it an environment or shell variable, use the unset command:

Make sure that such variable no longer exists:

No result was printed because the variable was reset.

Automatically setting environment variables

As already mentioned, many programs use environment variables to determine how they should operate. Setting the necessary variables every time a new shell is created is quite inconvenient. In addition, many variables are set immediately upon login. How to set variables automatically?

This is a little more complicated than it seems at first, since the bash shell reads a lot of configuration files.

Types of Shell Sessions

The bash shell reads different configuration files depending on how the session was started. The first two types of sessions that define a shell are start and child.

Starter or initial shell(login shell) is a shell session that opens after user authorization. If the user logs into a terminal or authenticates using SSH, a startup shell will be opened.

If a new session is started from an authorized (start) session (as in the previous examples a new bash shell was started), this session will be subsidiary (non-login shell). To open this session, you do not need to go through the authorization procedure.

Also, shell sessions can be interactive or non-interactive.

Interactive session shell (interactive shell) is a session tied to a terminal. A non-interactive shell session is a session that is not associated with a terminal.

So, shell sessions are classified according to the following aspects: start-child, interactive-non-interactive.

A normal session opened using SSH is typically an interactive start session. A script run via the command line typically runs in a non-interactive child session. A terminal session is a different combination of these two properties.

By classifying a session as a start session or a child session, the system understands which files need to be read to initialize the shell session.

So, first the startup session gets the configurations from the /etc/profile file. It then looks for the startup shell configuration file in the user's home directory to obtain user-defined configurations.

This session reads the files ~/.bash_profile, ~/.bash_login and ~/.profile and does not read other files.

The child session in turn reads /etc/baash.bashrc and then the user's ~/.bash.rc file to deploy the environment.

Non-interactive shells read the BASH_ENV environment variable and the specified file to create a new environment.

How to set environment variables

As you can see, the configurations are scattered across different files.

This makes the system very flexible, which is useful in certain situations when you need to set different parameters for the start and child shells. However, these shells generally use the same settings.

Fortunately, most Linux distributions point to the child shell configuration file as the source of the startup shell configurations. This means that you can define environment variables for both sessions in the child shell's configuration files.

Typically, both shells use user-defined environment variables. This means that you can set these variables in the ~/.bashrc file.

Open this file:

Most likely, it already contains some data. Most of the values ​​set here are bash options and have nothing to do with environment variables. The variables in this file are set in exactly the same way as on the command line:

export VARNAME=value

After entering all the necessary variables, close the file. The next time you start a shell session, the variables set here will be read and passed to the shell environment. To tell the current session to read the given file, enter:

source ~/.bashrc

To set system-wide variables, add them to /etc/profile, /etc/bash.bashrc, or /etc/environment.

Results

Shell and environment variables are always present in all shell sessions, so knowing how to work with them is especially useful. They can be used to pass parent process configurations to child processes, as well as configure settings outside of files.

This provides a number of advantages in certain situations. For example, some deployment mechanisms rely on environment variables to configure authentication information. This is convenient because such important data will not be stored in any file, which means it will be reliably protected from outsiders.

There are many other more common situations in which you may need to read variables or change the system environment. The tools and techniques described in this guide provide an excellent foundation for developing your skills in working with variables and using them correctly.

Tags: ,

Environment variables in Linux are special variables defined by the shell and used by programs at runtime. They can be defined by the system and the user. Linux system environment variables are defined by the system and used by system-level programs.

For example, the PWD command uses a system variable to keep the previous working directory. User environment variables are set by the user, for the current shell, either temporarily or permanently. The whole concept of adding and removing shell variables revolves around multiple files, commands, and different shells.

More broadly, an environment variable can be of three types:

1. Local environment variables

These variables are defined only for the current session. They will be permanently erased after the end of the session, be it remote access or a terminal emulator. They are not stored in any files, but are created and deleted using special commands.

2. Custom Shell Variables

These shell variables in Linux are defined for a specific user and are loaded each time the user logs in using a local terminal or connects remotely. Such variables are typically stored in configuration files: .bashrc, .bash_profile, .bash_login, .profile or other files located in the user directory.

3. System environment variables

These variables are available throughout the system, for all users. They are loaded at system startup from the system configuration files: /etc/environment, /etc/profile, /etc/profile.d/ /etc/bash.bashrc.

Linux Environment Variable Configuration Files

Here we will take a quick look at the various configuration files listed above that are used to configure environment variables for the entire system or a specific user.

.bashrc

This is a user-specific variable file. Loaded every time the user creates a terminal session, that is, in other words, opens a new terminal. All environment variables created in this file take effect every time a new terminal session is started.

.bash_profile

These variables take effect every time the user connects remotely via SSH. If this file is missing the system will look for .bash_login or .profile.

/etc/environment

This file is for creating, editing and deleting any environment variables at the system level. Environment variables created in this file are available for the entire system, for each user, and even when connecting remotely.

/etc/bash.bashrc

System bashrc. This file is executed for each user, every time he creates a new terminal session. This only works for local users; when connected via the Internet, such variables will not be visible.

/etc/profile

System file profile. All variables from this file are available to any user on the system only if he is logged in remotely. But they will not be available when creating a local terminal session, that is, if you simply open the terminal.

All Linux environment variables created using these files can be removed simply by deleting them from there. Only after each change, you need to either log out and log back in, or run this command:

source filename

Adding User and System Environment Variables in Linux

Now that you know a little theory, let's move on to practice. Local environment variables in Linux can be created with the following commands:

var=value
$ export var=value

These variables will only be available for the current terminal session.

There are several commands you can use to remove environment variables:

1. Using env

By default, you can use env to view all set environment variables. But with the -i option, it allows you to temporarily remove all shell variables and execute the command without variables.

env –i command

Var is any variable you want to pass to this command.

This command will start the shell without any environment variables at all:

After launching such an environment, no variables will be available, but after exiting everything will return to its place.

2. Using unset

This is another way to remove Linux environment variables. Unset removes a variable by name until the end of the current session:

unset variable_name

3. Set the variable value to ""

This is the easiest way to remove environment variables in Linux; by setting a variable to empty, you remove it for the rest of the current session.

Note: Using these methods you can change the values ​​of system or user variables, but they will only be relevant for the current session.

Creating User and System Environment Variables

In this section, we'll look at how to set and delete system and user variables not only for the current session, but so that the effect persists after a reboot.

1. Set and remove local variables in Linux

Let's create a local variable VAR and set it to any value, then unset it and make sure it is deleted:

VAR1="Losst"
$ echo $VAR1
$unset VAR1
$ echo $VAR1

Another way to create a variable is with the export command. Let's remove it by assigning an empty value:

export VAR="Losst"
$ echo $VAR
$VAR=
$ echo $VAR

Now let's create a variable VAR2 and give it a value. And then temporarily remove all local variables by running env -i. It will start a shell without any variables. After entering exit, all variables will be restored.

VAR2="Losst"
$ echo $VAR2
$ env -i bash
$ echo $VAR2

Setting and Removing User Variables

Edit the .bashrc file in your home directory by adding an export command to export the desired variable. Then run the source command to apply the changes. Let's create, for example, the CD variable:

Add this line (o, then paste, then Esc and :wq):

export CD="This is Lost Home"

Now it remains to update the configuration:

source.bashrc
$echo $CD

To remove this variable, simply remove it from .bashrc.

Now let's add an environment variable using .bash_profile. This variable, as you already know, will only be available during remote login:

vi .bash_profile

Add the line:

export VAR2="This is Lost Home"

And run these commands to apply the changes and check that the variable has been added:

source.bash_profile
$ echo $VAR2

The variable is not available because you have created a local terminal session, now connect via ssh:

ssh user@localhost
$ echo $VAR2

You can delete this environment variable in the same way as in the previous case by deleting it from the file.

Comment: These variables are always available, but not for all users.

Setting and removing system environment variables

Let's create a variable available to all users in all terminal sessions except remote ones by adding it to /etc/bash.profile:

vi /etc/bash.profile

export VAR="This is system-wide variable"

Then we update:

source /etc/bash.bashrc

Now this variable is available to all users, in all terminals:

echo $VAR
$sudo su
$ echo $VAR
$su -
$ echo $VAR

If you want to make an environment variable available to all users who connect to this machine remotely, edit the /etc/profile file:

export VAR1="This is system-wide variable for only remote sessions"

Update the configuration and check the availability of the variable, it will only be available remotely:

source /etc/profile
$ echo $VAR1

If you need to add an environment variable in Linux so that it is accessible both remotely and for local sessions, export it to /etc/environment:

vi /etc/environment

export VAR12="I am available everywhere"

We check:

source /etc/environment
$ echo $VAR12
$sudo su
$ echo $VAR12
$ exit
$ssh localhost
$ echo $VAR12

2.2. Environment Variables

The operating system supports a special type of resource called Environment Variables (environment variables). These variables are a pair NAME - VALUE . The name can start with a letter and consist of letters, numbers, and underscores.

To substitute the value of a variable on the command line, precede the variable name with a $ sign:

$ echo $USER guest

If the variable is not set, an empty string is returned.

To set the value of a variable, use the assignment operator (in the case of Bourne-like shells):

$TEST=test

or the built-in set operator (in the case of C-like ones):

$ set TEST=test

The set command, without arguments, lists the values ​​of all variables set in the environment:

$ set COLUMNS=197 CVS_RSH=ssh DIRSTACK=() EUID=1000 GROUPS=() G_BROKEN_FILENAMES=1 HISTFILE=/home/guest/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOME=/home/guest HOSTNAME=myhost HOSTTYPE=i686 IFS =$" \t\n" INPUTRC=/etc/inputrc KDEDIR=/usr KDEDIRS=/home/guest/.local/ KDE_IS_PRELINKED=1 KDE_NO_IPV6=1 LANG=ru_RU.UTF-8 LESSOPEN="|/usr/bin/ lesspipe.sh %s" LINES=65 LOGNAME=guest ....

Variables can be local for a given process or global for a session. You can set local values ​​for variables by preceding them by calling the commands:

$ TEST=test1 sh -c "echo $TEST" test1

You can evaluate the contents of a set of variables for a session by calling the interpreter's built-in command env in the case of Bourne-like interpreters (sh, ksh, bash, zsh, pdksh...), and printenv in the case of C-Shell clone interpreters (csh, tcsh. ..):

$ env HOSTNAME=myhost TERM=xterm SHELL=/bin/bash HISTSIZE=1000 KDE_NO_IPV6=1 SSH_CLIENT=172.16.0.9 50487 22 QTDIR=/usr/lib/qt-3.3 QTINC=/usr/lib/qt-3.3/include SSH_TTY =/dev/pts/6 USER=guest MOZILLA_CERTIFICATE_FOLDER=/home/guest/.evolution/ KDEDIR=/usr MAIL=/var/spool/mail/guest PATH=/usr/games:/usr/local/bin:/bin :/usr/bin:/home/guest/bin INPUTRC=/etc/inputrc PWD=/home/guest KDE_IS_PRELINKED=1 LANG=ru_RU.UTF-8 KDEDIRS=/home/guest/.local/ SSH_ASKPASS=/usr/libexec /openssh/gnome-ssh-askpass SHLVL=1 HOME=/home/guest LOGNAME=guest QTLIB=/usr/lib/qt-3.3/lib CVS_RSH=ssh SSH_CONNECTION=172.16.0.9 50487 172.16.2.9 22 LESSOPEN=|/usr /bin/lesspipe.sh %s G_BROKEN_FILENAMES=1 _=/bin/env

Command Sets Shell can be compiled into command files called scripts, where the first line in a special type of comment specifies the command interpreter for executing this set. For example, let's create a file in a text editor called test with the following content:

#!/bin/sh echo TEST variable: echo $TEST

This program will print to standard output the text message "TEST variable: " and the value of the TEST variable, if specified. You can run it from the command line by passing it as a parameter to the command interpreter:

$sh test TEST variable:

You can make a variable global using the export (Bourne) or setenv (C-SHell) statement:

$ export TEST=test1 $ sh test TEST variable: test1

You can set local values ​​of variables for executing a given program by preceding them by calling the commands:

$ TEST=test2 sh test TEST variable: test2

Removing environment variables is done using the unset statement.

The concept of a parameter in the shell bash similar to the concept of a variable in conventional programming languages. The parameter name (or identifier) ​​can be a word consisting of alphabetic characters, numbers, and underscores (only the first character of the word cannot be a number), a number, or one of the following special characters: * , @ , # , ? , - (hyphen), $ , ! , 0 , _ (underlining).

A parameter is said to be set or set if a value is assigned to it. The value can also be an empty string. To display the value of a parameter, use the symbol $ before his name. Yes, team

$ echo name

will display the word on the screen name, and the team

$echo $name

will return the value of the name variable (if one is set, of course).

5.6.1 Varieties of parameters

Parameters are divided into three classes: positional parameters, special parameters(the names of which are the special characters just listed) and shell variables.

Names (identifiers) positional parameters consist of one or more digits (not a single zero). The positional parameter values ​​are the arguments that were given when the shell started (the first argument is the value of positional parameter 1, etc.). You can change the value of a positional parameter using the built-in command set. The values ​​of these parameters also change while the shell is executing one of the functions (this will be discussed below, in section 5.8).

Special parameters are patterns, replacement (substitution) of which is carried out as follows.

Table 5.2. Special parameters.

Parameter

Substitution rules

Replaced with positional parameters, starting from the first one. If the replacement is made inside double quotes, then this parameter is replaced with a single word made up of all positional parameters, separated by the first character of the special IFS variable (discussed below). That is, ``$*"" is equivalent to ``$1c$2c...", where c is the first character in the value of the IFS variable. If IFS is set to empty or has no value set, the parameters are separated by spaces

Replaced with positional parameters, starting from the first one. If the replacement is made inside double quotes, then each parameter is replaced with a separate word. Thus, `` $@"" is equivalent to ""$1"" ""$2"" ... If there are no positional parameters, then no value is assigned (the @ parameter is simply removed)

Replaced with the decimal value of the number of positional parameters

Replaced by the exit status of the last foreground program channel running

(hyphen)

Replaced with the current set of flag values ​​set using the builtin command set or when starting the shell itself

Replaced with the process identifier (P ID) of the shell

Replaced with the process identifier (P ID) of the most recently executed background (asynchronously executed) command

Replaced with the name of the shell or script to run. If bash runs to execute a batch file, $0 is the name of the file. Otherwise this value is equal to the full path to the shell

(underline)

Replaced with the last argument of the previous command executed (if this is a parameter or variable, then its value is substituted)

The special parameters listed in the table above differ in that they can only be referenced; You cannot assign values ​​to them.

Variable from the shell's point of view, it is a parameter denoted by a name. Values ​​are assigned to variables using the following operator:

$name=value

Where name is the name of the variable, and value— the value assigned to it (can be an empty string). The variable name can only consist of numbers and letters and cannot begin with a number. The value can be any text. If a value contains special characters, it must be enclosed in quotes. The assigned value does not contain these quotes, of course. If the variable is set, it can be removed using the shell builtin command unset.

The set of all set shell variables with their assigned values ​​is called the environment or shell environment. You can view it using the command set without parameters (just maybe you should organize a pipeline "set | less"). The output of this command lists all environment variables in alphabetical order. To view the value of one specific variable, you can instead of the command set(in the output of which you can still search and search for the desired variable) you can use the command

$echo $name

(however, in this case you must know the name of the variable you are interested in).

Among the variables you will see in the command output are set, there are some very interesting variables. For example, pay attention to the RANDOM variable. If you run the command several times in a row

$ echo $RANDOM

you will get a new value each time. The fact is that this variable returns a random integer from the interval 0 - 32,768.

5.6.2 Shell prompts

One of the very important variables has a name PS1. This variable specifies the type of invitation that bash Outputs when it is waiting for the next command to be entered by the user. By default, this variable is set to "\s-\v\$ ". Actually in bash There are four invitations that are used in different situations. Variable PS1 specifies the type of prompt that is issued when the shell is waiting for a command to be entered. Secondary prompt specified by variable PS2, appears when the shell is waiting for the user to enter some more data necessary for the continuation of the running command or program. Default variable PS2 has the meaning " >" . You may have already seen this prompt when you ran the command cat to enter data from the keyboard into a file. Another example is the command ftp, after launching which the invitation also takes this form.

Variable prompt PS3, used in command select. Variable prompt PS4, is printed before each command at the time bash monitors the progress of execution. The default value is " + ".

If you so desire, you can change the type of variables PS1 And PS2. In this case, you can use any symbols entered from the keyboard, as well as a certain number of special characters, which, when generating the prompt string, are decoded in accordance with Table. 5.3 (we list only some of them, for example; for a complete list, see the man page for the utility bash) .

Table 5.3. Special characters for generating an invitation

Symbol

Its meaning

Beep (ASCII code 07)

Date in the format "Day, month, day", for example, Wed, Oct, 17.

Hostname up to the first dot

Full hostname

Current time in 24-hour format: HH:MM:SS (hours:minutes:seconds)

Current time in 12 hour format: HH:MM:SS

Current time in 12-hour format am/pm

Name of the user who started the shell

Full name of the current working directory (starting at root)

Current working directory (no path specified)

The # symbol if the shell is running as superuser, and the symbol $ , if the shell is started by a normal user.

\nnn

The character having the octal code nnn

New line (line feed)

Shell name

Current team number

A backslash

Beginning of a sequence of non-printing characters (this character can be used to include a sequence of terminal control characters in the tooltip text)

End of sequence of non-printable characters

The serial number of this command in the history of commands

The current command number (the serial number of the command being executed within the current session) may differ from the number of this command in the command history list, since the latter includes commands that were saved in the command history file.

Once the value of a variable defining a hint has been read by the shell, substitutions can be made to it according to the rules for parameter expansion, substitutions in command names and arithmetic expressions, and word splitting. These rules will be discussed below, in section. 5.7.

For example, after executing the command (since there is a space in the string, quotes are required)

# PS1="[\u@\h \W]\$"

the standard prompt will display a square bracket, username, symbol @ , computer name, space, current directory name (without path), closing square bracket and symbol $ (if a simple user is running in the shell) or # (if the shell is running as root).

5.6.3 Variable PATH

Another very important variable has a name PATH. It specifies a list of paths to directories in which bash searches for files (in particular, files with commands) in cases where the full path to the file is not specified on the command line. Individual directories in this list are separated by colons. Default variable PATH includes directories /usr/local/bin, /bin, /usr/bin, /usr/X11R6/bin, i.e. it looks like:

/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:

In order to add a directory to this list, you need to run the following command:

# PATH=$PATH:new_path.

When performing a search, the shell searches the directories in the order they are listed in the PATH variable.

Note that you can include the current directory in this list by adding a period to the PATH variable. However, this is not recommended for security reasons: an attacker could put a command in a public directory whose name matches one of the commands frequently executed by the superuser, but performs completely different actions (especially if the current directory is at the beginning of the list of search paths).

5.6.4 Variable IFS

This variable specifies the Internal Field Separator that is used in the word splitting operation of command line conversions performed by the shell before running the command line for execution. The default value of this variable is "<Пробел><Символ_ новой_ строки>".

5.6.5 Current and home directories

The name of the current directory is stored in an environment variable (named PWD), and the value of this variable changes each time the program is started CD(and also when changing the current directory in any other way, for example, through Midnight Commander).

Similarly, the full name (and path) of the home directory of the user who launched the process is stored in the HOME variable.

5.6.6 Team export

When the shell runs a program or command, it passes some environment variables to them. In order for an environment variable to be passed to a process launched from the shell, it must be set using a special command export, i.e. instead

$name=value

need to write it down

$export name=value

In this case, all programs launched from the shell (including secondary instances of the shell itself) will have access to the variables defined in this way, i.e., they can call their values ​​by name.

V. Kostromin (kos at rus-linux dot net) - 5.6. Parameters and variables. Shell environment