Bash variables

Introduction

Bash variables are divided into environment variables and custom variables.

Environment variables

Environment variables are the variables that come with the Bash environment. They have been defined when entering the Shell and can be used directly. They are usually defined by the system, and can also be passed into the child shell from the parent shell by the user.

The env command or the printenv command can display all environment variables.

$ env
# Or
$ printenv

Below are some common environment variables.

  • BASHPID: The process ID of the Bash process.
  • BASHOPTS: The parameters of the current Shell, you can use the shopt command to modify.
  • DISPLAY: The name of the display in the graphics environment, usually :0, indicating the first display of the X Server.
  • EDITOR: The default text editor.
  • HOME: The user's home directory.
  • HOST: The name of the current host.
  • IFS: The separator between words, the default is a space.
  • LANG: Character set and language encoding, such as zh_CN.UTF-8.
  • PATH: A list of directories separated by colons. When the executable program name is entered, this directory list will be searched.
  • PS1: Shell prompt.
  • PS2: The secondary Shell prompt when entering multiple lines of commands.
  • PWD: current working directory.
  • RANDOM: Returns a random number between 0 and 32767.
  • SHELL: The name of Shell.
  • SHELLOPTS: Start the parameters of the set command of the current Shell, see the chapter "set command".
  • TERM: The name of the terminal type, which is the protocol used by the terminal emulator.
  • UID: The ID number of the current user.
  • USER: The user name of the current user.

Many environment variables rarely change, and they are read-only and can be regarded as constants. Since their variable names are all uppercase, traditionally, if users want to define a constant by themselves, they will also use all uppercase variable names.

Note that Bash variable names are case sensitive, and HOME and home are two different variables.

To view the value of a single environment variable, you can use the printenv command or the echo command.

$ printenv PATH
# Or
$ echo $PATH

Note that the variable name after the printenv command does not need to be prefixed with $.

Custom variables

Custom variables are variables defined by the user in the current Shell. They must be defined first and then used, and are only available in the current Shell. Once you exit the current Shell, the variable does not exist.

The set command can display all variables (including environment variables and custom variables), as well as all Bash functions.

$ set

Create variables

When the user creates a variable, the variable name must comply with the following rules.

  • It consists of letters, numbers and underscore characters.
  • The first character must be a letter or an underscore, not a number.
  • Spaces and punctuation marks are not allowed.

The syntax of variable declaration is as follows.

variable=value

In the above command, the left side of the equal sign is the variable name, and the right side is the variable. Note that there can be no spaces on either side of the equal sign.

If the value of the variable contains spaces, you must enclose the value in quotation marks.

myvar="hello world"

Bash has no concept of data types, and all variable values ​​are strings.

Below are some examples of custom variables.

a=z # variable a is assigned to string z
b="a string" # The variable value contains spaces, so it must be enclosed in quotation marks
c="a string and $b" # Variable value can refer to the value of other variables
d="\t\ta string\n" # Variable values ​​can use escape characters
e=$(ls -l foo.txt) # Variable value can be the result of command execution
f=$((5 * 7)) # Variable value can be the result of mathematical operation

Variables can be assigned repeatedly, and subsequent assignments will overwrite previous assignments.

$ foo=1
$ foo=2
$ echo $foo
2

In the above example, the second assignment of the variable foo will overwrite the first assignment.

If multiple variables are defined on the same line, they must be separated by semicolons (;).

$ foo=1;bar=2

In the above example, the two variables foo and bar are defined on the same line.

Read variables

When reading a variable, just add $ in front of the variable name.

$ foo=bar
$ echo $foo
bar

Whenever Shell sees a word beginning with $, it will try to read the value corresponding to the variable name.

If the variable does not exist, Bash will not report an error, but will output a null character.

Since $ has a special meaning in Bash, you must be very careful when using it as a dollar sign.

$ echo The total is $100.00
The total is 00.00

The original intent of the above command is to enter $100, but Bash interprets $1 as a variable, which is empty, so the input becomes 00.00. Therefore, if you want to use the original meaning of $, you need to put a backslash in front of $ to escape it.

$ echo The total is \$100.00
The total is $100.00

When reading variables, the variable name can also be surrounded by curly braces {}, for example, $a can also be written as ${a}. This type of writing can be used when the variable name is used in conjunction with other characters.

$ a=foo
$ echo $a_file

$ echo ${a}_file
foo_file

In the above code, the variable name a_file will not have any output, because Bash interprets it as a variable, and this variable does not exist. Only use curly braces to distinguish $a, Bash can interpret it correctly.

In fact, the syntax $foo for reading variables can be seen as a shorthand for ${foo}.

If the value of the variable itself is also a variable, you can use the syntax of ${!varname} to read the final value.

$ myvar=USER
$ echo ${!myvar}
ruanyf

In the above example, the value of the variable myvar is USER, and the writing of ${!myvar} expands it to the final value.

If the variable value contains consecutive spaces (or tabs and newlines), it is best to read it in double quotes.

$ a="1 2 3"
$ echo $a
1 2 3
$ echo "$a"
1 2 3

In the above example, the value of the variable a contains two consecutive spaces. If you read directly, Shell will combine consecutive spaces into one. Only read in double quotation marks can keep the original format.

Delete variable

The unset command is used to delete a variable.

unset NAME

This command is not very useful. Because the non-existent Bash variable is always equal to the empty string, even if the variable is deleted by the unset command, the variable can still be read and the value is an empty string.

Therefore, to delete a variable, you can also set this variable to an empty string.

$ foo=''
$ foo=

In the above two ways of writing, the variable foo is deleted. Since the non-existent value defaults to an empty string, the latter method can write no value on the right side of the equal sign.

Output variables, export command

The variables created by the user can only be used in the current shell, and the child shell cannot read the variables defined by the parent shell by default. In order to pass variables to the child shell, the export command is used. The variables output in this way are environment variables for the child shell.

The export command is used to export variables to the sub-Shell.

NAME=foo
export NAME

The above command outputs the variable NAME. Variable assignment and output can also be done in one step.

export NAME=value

After the above command is executed, the current Shell and the newly created sub-Shells can read the variable $NAME.

If the child shell modifies the inherited variables, the parent shell will not be affected.

# Output variable $foo
$ export foo=bar

# New sub Shell
$ bash

# Read $foo
$ echo $foo
bar

# Modify inherited variables
$ foo=baz

# Exit sub Shell
$ exit

# Read $foo
$ echo $foo
bar

In the above example, the child Shell modifies the inherited variable $foo, which has no effect on the parent Shell.

Special variables

Bash provides some special variables. The values ​​of these variables are provided by Shell, and users cannot assign values.

(1) $?

$? is the exit code of the previous command, used to determine whether the previous command was executed successfully. The return value is 0, indicating that the previous command was executed successfully; if it is non-zero, the previous command failed to execute.

$ ls doesnotexist
ls: doesnotexist: No such file or directory

$ echo $?
1

In the above example, the ls command looks at a non-existent file, resulting in an error. $? is 1, indicating that the execution of the previous command failed.

(2) $$

$$ is the process ID of the current Shell.

$ echo $$
10662

This special variable can be used to name temporary files.

LOGFILE=/tmp/output_log.$$

(3) $_

$_ is the last parameter of the previous command.

$ grep dictionary /usr/share/dict/words
dictionary

$ echo $_
/usr/share/dict/words

(4) $!

$! is the process ID of the last asynchronous command executed in the background.

$ firefox &
[1] 11064

$ echo $!
11064

In the above example, firefox is a command running in the background, and $! returns the process ID of the command.

(5) $0

$0 is the name of the current shell (when executed directly on the command line) or script name (when executed in a script).

$ echo $0
bash

In the above example, $0 returns that Bash is currently running.

(6) $-

$- is the startup parameter of the current Shell.

$ echo $-
himBHs

(7) $@ and $#

$@ and $# indicate the number of parameters of the script, see the chapter on scripts.

The default value of the variable

Bash provides four special syntaxes, which are related to the default value of the variable, the purpose is to ensure that the variable is not empty.

${varname:-word}

The meaning of the above grammar is that if the variable varname exists and is not empty, then its value is returned, otherwise word is returned. Its purpose is to return a default value. For example, ${count:-0} means that the variable count does not exist and returns 0.

${varname:=word}

The meaning of the above grammar is that if the variable varname exists and is not empty, then its value is returned, otherwise it is set to word and word is returned. Its purpose is to set the default value of the variable. For example, ${count:=0} means that when the variable count does not exist, it returns 0 and sets count to 0.

${varname:+word}

The meaning of the above grammar is that if the variable name exists and is not empty, it will return word, otherwise it will return a null value. Its purpose is to test whether the variable exists. For example, ${count:+1} means that when the variable count exists, it returns 1 (meaning true), otherwise it returns a null value.

${varname:?message}

The meaning of the above grammar is that if the variable varname exists and is not empty, its value will be returned, otherwise it will print out varname: message and interrupt the execution of the script. If message is omitted, the default message "parameter null or not set." will be output. Its purpose is to prevent variables from being undefined. For example, ${count:?"undefined!"} means that when the variable count is undefined, the execution will be interrupted, an error will be thrown, and the given error message undefined! will be returned.

If the above four syntaxes are used in a script, the part of the variable name can use numbers from 1 to 9 to indicate the parameters of the script.

filename=${1:?"filename missing."}

The above code appears in the script, and 1 represents the first parameter of the script. If the parameter does not exist, exit the script and report an error.

declare command

The declare command can declare some special types of variables and set some restrictions for variables, such as declaring read-only variables and integer variables.

Its grammatical form is as follows.

declare OPTION VARIABLE=value

The main parameters (OPTION) of the declare command are as follows.

  • -a: Declare array variables.
  • -f: Output all function definitions.
  • -F: Output all function names.
  • -i: Declare integer variables.
  • -l: Declare variables as lowercase letters.
  • -p: View variable information.
  • -r: Declare read-only variables.
  • -u: Declare variables as capital letters.
  • -x: This variable is output as an environment variable.

If the declare command is used in a function, the declared variable is only valid inside the function, which is equivalent to the local command.

Without any parameters, the declare command outputs all variables of the current environment, including functions, which is equivalent to the set command without any parameters.

$ declare

(1) -i parameter

After the integer variable is declared with the -i parameter, mathematical operations can be performed directly.

$ declare -i val1=12 val2=5
$ declare -i result
$ result=val1*val2
$ echo $result
60

In the above example, if the variable result is not declared as an integer, val1*val2 will be treated as a literal, and integer operations will not be performed. In addition, val1 and val2 do not need to be declared as integers, because as long as result is declared as an integer, its assignment will be automatically interpreted as an integer operation.

Note that after a variable is declared as an integer, it can still be rewritten as a string.

$ declare -i var=12
$ var=foo
$ echo $var
0

In the above example, the variable var is declared as an integer. After overwriting, Bash will not report an error, but will assign an indeterminate value. In the above example, 0 or 3 may be output.

(2) -x parameter

The -x parameter is equivalent to the export command, which can output an environment variable whose variable is a sub-Shell.

$ declare -x foo
# Equivalent to
$ export foo

(3) -r parameter

The -r parameter can declare read-only variables, cannot change the value of the variable, and cannot unset the variable.

$ declare -r bar=1

$ bar=2
bash: bar: read-only variable
$ echo $?
1

$ unset bar
bash: bar: read-only variable
$ echo $?
1

In the above example, the last two assignment statements will report errors and the command execution fails.

(4) -u parameter

The -u parameter declares that the variable is in uppercase letters, and the variable value can be automatically converted to uppercase letters.

$ declare -u foo
$ foo=upper
$ echo $foo
UPPER

(5) -l parameter

The -l parameter declares that the variable is in lowercase letters, and the variable value can be automatically converted to lowercase letters.

$ declare -l bar
$ bar=LOWER
$ echo $bar
lower

(6) -p parameter

The -p parameter outputs variable information.

$ foo=hello
$ declare -p foo
declare - foo="hello"
$ declare -p bar
bar: not found

In the above example, declare -p can output the value of the defined variable, and for the undefined variable, it will prompt that it cannot be found.

If you do not provide a variable name, declare -p outputs information about all variables.

$ declare -p

(7) -f parameter

The -f parameter outputs all functions of the current environment, including its definition.

$ declare -f

(8) -F parameter

The -F parameter outputs the names of all functions in the current environment, excluding function definitions.

$ declare -F

readonly command

The readonly command is equivalent to declare -r, which is used to declare a read-only variable. The value of the variable cannot be changed, and the variable cannot be unset.

$ readonly foo=1
$ foo=2
bash: foo: read-only variable
$ echo $?
1

In the above example, changing the read-only variable foo will report an error and the command execution will fail.

The readonly command has three parameters.

  • -f: The declared variable is the function name.
  • -p: Print out all read-only variables.
  • -a: The declared variable is an array.

let command

When the let command declares a variable, you can directly execute arithmetic expressions.

$ let foo=1+2
$ echo $foo
3

In the above example, the let command can directly calculate 1 + 2.

If the parameter expression of the let command contains spaces, quotation marks are required.

$ let "foo = 1 + 2"

let can assign values ​​to multiple variables at the same time, and use spaces to separate the assignment expressions.

$ let "v1 = 1" "v2 = v1++"
$ echo $v1,$v2
2,1

In the above example, let declares two variables v1 and v2, where v2 is equal to v1++, which means that the value of v1 is returned first, and then v1 is incremented.

For the operators supported by this grammar, refer to the chapter "Arithmetic Operations in Bash".