congdong007

Penetration Test、Software Developer

0%

Bash Scripting 02 - Variables

Variables are named places to temporarily store data. We can set (or “declare”) a variable, which
assigns a value to it, or read a variable, which will “expand” or “resolve” it to its stored value.

We can declare variable values in a number of ways. The easiest method is to set the value directly
with a simple name=value declaration. Notice that there are no spaces before or after the “=” sign:

1
kali@kali:~$ first_param=Super

Declaring a variable is pointless unless we can reference it. To do this, we precede the variable with
the “$” character. Whenever Bash encounters this syntax in a command, it replaces the variable
name with its value (“expands” the variable) before execution:

1
2
3
4
kali@kali:~$ first_param=Super
kali@kali:~$ last_param=Hero
kali@kali:~$ echo $first_param $last_param
Super Hero

Variable names may be uppercase, lowercase, or a mixture of both. However, Bash is casesensitive so we must be consistent when declaring and expanding variables. In addition, it’s good
practice to use descriptive variable names, which make our scripts much easier to read and
maintain.

Be advised that Bash interprets certain characters in specific ways. For example, this declaration
demonstrates an improper multi-value variable declaration:

1
2
kali@kali:~$ greeting=Hello World
bash: World: command not found

This was not necessarily what we expected. To fix this, we can use either single quotes () or double
quotes () to enclose our text. However, Bash treats single and double quotes differently. When
encountering single quotes, Bash interprets every enclosed character literally. When enclosed in
double quotes, all characters are viewed literally except “$”, “`”, and “" meaning variables will be
expanded in an initial substitution pass on the enclosed text.

A simple example will help clarify this:

1
2
3
4
5
6
kali@kali:~$ greeting='Hello World'
kali@kali:~$ echo $greeting
Hello World
kali@kali:~$ greeting2="New $greeting"
kali@kali:~$ echo $greeting2
New Hello World

In this example, the single-quote-enclosed declaration of greeting preserved the value of our text
exactly and did not interpret the space as a command delimiter. However, in the double-quoteenclosed declaration of greeting2, Bash expanded $greeting to its value (“Hello World”), honoringthe special meaning of the “$” character.
We can also set the value of the variable to the result of a command or program. This is known as
command substitution, which allows us to take the output of a command or program (what
would normally be printed to the screen) and have it saved as the value of a variable.
To do this, place the variable name in parentheses “()”, preceded by a “$” character:

1
2
3
kali@kali:~$ user=$(whoami)
kali@kali:~$ echo $user
kali

Here we assigned the output of the whoami command to the user variable. We then
displayed its value. An alternative syntax for command substitution using the backtick, or grave,
character (`) is shown below:

1
2
3
kali@kali:~$ user2=`whoami`
kali@kali:~$ echo $user2
kali

The backtick method is older and typically discouraged as there are differences in how the two
methods of command substitution behave. It is also important to note that command
substitution happens in a subshell and changes to variables in the subshell will not alter variables
from the master process. This is demonstrated in the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kali@kali:~$ cat ./subshell.sh
#!/bin/bash -x
var1=value1
echo $var1
var2=value2
echo $var2
$(var1=newvar1)
echo $var1
`var2=newvar2`
echo $var2
kali@kali:~$ ./subshell.sh
+ var1=value1
+ echo value1
value1
+ var2=value2
+ echo value2
value2
++ var1=newvar1
+ echo value1
value1
++ var2=newvar2
+ echo value2
value2
kali@kali:~$

In this example, first note that we changed the shebang, adding in the -x flag. This instructed Bash
to print additional debug output, so we could more easily see the commands that were executed
and their results. As we view this output, notice that commands preceded with a single “+” character
were executed in the current shell and commands preceded with a double “++” were executed in a
subshell.
This allows us to clearly see that the second declarations of var1 and var2 happened inside a
subshell and did not change the values in the current shell as the initial declarations did.