Shell variables and expansions.

Shell variables and expansions.

·

5 min read

Expansions.

From our previous discussion on wildcards, we know a little bit about expansions. For example, the * character expands to include all characters present. This expansion occurs before any shell command is executed hence the shell would not see the * only its expanded characters. This is true for most wildcards as William Schotts explains in this article. The problem of how to print these character wildcards is by using escape character sequences. The \ , ' - which treats all characters within it as non-special and " which suppresses all special meanings of characters except $,\ and ` .

Brace expansions.

Brace expansions are special in that they expand to each term in the brace. ranges can also be used in braces as we'll see in the examples and as William Schotts explains.

Shell Variables.

The shell gives the ability to create and use variables. Variables could be described as special containers that hold given values. Variable names can be used to access and manipulate that variable content.

Alias.

The alias feature, allows one to create an alias of a given command. If you commonly mistype a command, the alias feature can be truly helpful. Aliases can be removed as explained here.

Some example applications of the above concepts.

  1. To create an alias of ls as rm * :

    alias ls="rm *" . This is straightforward as the command is given a value and it is set.

  2. A command that prints hello user, where user is the current Linux user, you'll have to use the USER environment variable that keeps track of the current user. The $ will give that variable. The echo command will have to use " since the variable has to be expanded. the full command would then be: echo "hello $USER" .

  3. To add /action to the PATH, you have to reset the path variable with the new path. Variables are set by stating their names and giving them a value. However, this goal requires an addition, not a reset. Therefore, the path variable has to be expanded to its initial one and the extra location added. Now the PATH variable consists of several locations that store the path to executables including commands. To add a path, the full path should be spelled out and the /action added to it separated by a colon. In this case, the path is stored in an existing variable that can be accessed using the $ sign. hence the command becomes: PATH = $PATH:/action .

  4. To list environment variables, use printenv.

  5. To list local variables, environment variables and functions, use set.

  6. To create a variable, give the variable name, equal sign then the value without spaces. i.e. to create a local variable called recuse with the value nox; recuse=nox .

  7. To create a global variable use the export keyword. e.g. to create a global variable with the values in 6; export recuse=nox.

  8. To print the result of the addition of 128 with the value stored in the environment variable TRUEKNOWLEDGE, followed by a new line:

    echo $((($TRUEKNOWLEDGE) + 128)) . This code works by using the $ to display the result and the second to evaluate the TRUEKNOWLEDGE as a variable.

  9. The division works similarly. e.g. To print the result of POWER divided by DIVIDE, followed by a new line where both are environment variables;

    echo $(($POWER / $DIVIDE)) .

  10. Converting to various bases in the shell is still an arithmetic operation. The shell will execute it similarly to other arithmetic operations i.e. $((expression)). The syntax for converting is, $((base#numbertoconvert)). To convert 85 to base 16, $((16#85))To convert a number stored in a variable, use the $ to tell bash to convert it to a number. To convert a number stored in BINARY to base 2 and display it, echo $((2#$BINARY)).

  11. The next example is an interesting application of brace expansions. The task is to print all possible combinations of two letters, using the English alphabet, except oo. This calls for printing all the letters, then piping them before printing to a command that will remove oo. Using brace expansions to get all possible combinations is fairly easy, echo {a..z}{a..z}. Of course, the quickest command to remove a given pattern is grep. This will happen when it is used with the -v option. Of course, grep displays a pattern. However, piping it directly to grep won't work since grep checks a pattern following a newline. The echo printing will put all its output in one line. The way to combat this is by converting the space between the letters in the output to a newline character using tr. The full command will therefore be: echo {a..z}{a..z} | tr ' ' '\n' | grep -v oo.

  12. This example looks at printing decimals (floats) to the output. The printf function provides an extremely simple and easy way to do this. It works similarly ( not the same) to the printf function found in the C programming language (run man printf to learn more). The way to print something using printf , in the shell (BASH shell), is by providing the string (characters) and when you wish to pass a variable, put the `%` before the conversion specifier, a letter stating the variable type. With float variables, the specifier is the letter f and the number of decimal places to use can be placed using a . after the % and the number of decimal places before using f. i.e. to print 4 decimal places %.4f. To print a number stored in NUM with two decimal places, followed by a new line;

    printf ".2f\n" $NUM .

  13. The next example is tricky since it looks at custom bases. The task reads;

    Write a shell script that adds the two numbers stored in the environment variables WATER and STIR and prints the result.

    • WATER is in base water

    • STIR is in base stir.

    • The result should be in base bestchol

      This is particularly challenging since the bases are not common numbers. The base water has 5 digits hence it can be translated to base 5 while stir has 4 hence it can be translated to base 4. First, water will be translated into digits and the result cast into each. Using printf and casting the bases: printf '%o\n' $(( 5#$( echo $WATER | tr water 01234) + 5#$( echo $STIR | tr stir. 01234 ) )) | tr 01234567 bestchol .

These examples should give you a good introduction to shell variables and expansions. Have fun practicing.