Bash advanced variables

Bash advanced variables
bash arrays

There are cases when you want to avoid this kind of behavior, for instance when handling telephone and other numbers. Apart from integers and variables, you may also want to specify a variable that is a constant. This is often done at the beginning of a script, when the value of the constant is declared. After that, there are only references to the constant variable name, so that when the constant needs to be changed, it only has to be done once. A variable may also be a series of variables of any type, a so-called array of variables (VAR0VAR1, VAR2, … VARN).

Using the declare built-in

Using a declare statement, we can limit the value assignment to variables.

The syntax for declare is the following:

declare OPTION(s) VARIABLE=value

The following options are used to determine the type of data the variable can hold and to assign it attributes:

Options to the declare built-in

Option Meaning
-a Variable is an array.
-f Use function names only.
-i The variable is to be treated as an integer; arithmetic evaluation is performed when the variable is assigned a value .
-p Display the attributes and values of each variable. When -p is used, additional options are ignored.
-r Make variables read-only. These variables cannot then be assigned values by subsequent assignment statements, nor can they be unset.
-t Give each variable the trace attribute.
-x Mark each variable for export to subsequent commands via the environment.

Using + instead of - turns off the attribute instead. When used in a function, declare creates local variables.

The following example shows how assignment of a type to a variable influences the value.

[local ~] declare -i VARIABLE=12

[local ~] VARIABLE=string

[local ~] echo $VARIABLE
0

[local ~] declare -p VARIABLE
declare -i VARIABLE="0"

Note that Bash has an option to declare a numeric value, but none for declaring string values. This is because, by default, if no specifications are given, a variable can hold any type of data.

Constants

In Bash, constants are created by making a variable read-only. The readonly built-in marks each specified variable as unchangeable. The syntax is:

readonly OPTION VARIABLE(s)

The values of these variables can then no longer be changed by subsequent assignment. If the -f option is given, each variable refers to a shell function. If -a is specified, each variable refers to an array of variables. If no arguments are given, or if -p is supplied, a list of all read-only variables is displayed. Using the -p option, the output can be reused as input.

The return status is zero, unless an invalid option was specified, one of the variables or functions does not exist, or -f was supplied for a variable name instead of for a function name.

[local ~] readonly TUX=penguinpower

[local ~] TUX=Mickeysoft
bash: TUX: readonly variable

Array variables

An array is a variable containing multiple values. Any variable may be used as an array. There is no maximum limit to the size of an array, nor any requirement that member variables be indexed or assigned contiguously. Arrays are zero-based: the first element is indexed with the number 0.

Indirect declaration is done using the following syntax to declare a variable:

ARRAY[INDEXNR]=value

The INDEXNR is treated as an arithmetic expression that must evaluate to a positive number.

Explicit declaration of an array is done using the declare built-in:

declare -a ARRAYNAME

A declaration with an index number will also be accepted, but the index number will be ignored. Attributes to the array may be specified using the declare and readonly built-ins. Attributes apply to all variables in the array; you can’t have mixed arrays.

Array variables may also be created using compound assignments in this format:

ARRAY=(value1 value2 … valueN)

Each value is then in the form of [indexnumber=]string. The index number is optional. If it is supplied, that index is assigned to it; otherwise the index of the element assigned is the number of the last index that was assigned, plus one. This format is accepted by declare as well. If no index numbers are supplied, indexing starts at zero.

Adding missing or extra members in an array is done using the syntax:

ARRAYNAME[indexnumber]=value

Remember that the read built-in provides the -a option, which allows for reading and assigning values for member variables of an array.

Dereferencing the variables in an array

In order to refer to the content of an item in an array, use curly braces. This is necessary, as you can see from the following example, to bypass the shell interpretation of expansion operators. If the index number is @ or *, all members of an array are referenced.

[local ~] ARRAY=(one two three)

[local ~] echo ${ARRAY[*]}
one two three

[local ~] echo $ARRAY[*]
one[*]

[local ~] echo ${ARRAY[2]}
three

[local ~] ARRAY[3]=four

[local ~] echo ${ARRAY[*]}
one two three four

Referring to the content of a member variable of an array without providing an index number is the same as referring to the content of the first element, the one referenced with index number zero.

Deleting array variables

The unset built-in is used to destroy arrays or member variables of an array:

[local ~] unset ARRAY[1]

[local ~] echo ${ARRAY[*]}
one three four

[local ~] unset ARRAY

[local ~] echo ${ARRAY[*]}
<--no output-->

NOT all shells support arrays, so they break compatibility.

Length of a variable

Using the ${#VAR} syntax will calculate the number of characters in a variable. If VAR is “*” or “@”, this value is substituted with the number of positional parameters or number of elements in an array in general. This is demonstrated in the example below:

[local ~] echo $SHELL
/bin/bash

[local ~] echo ${#SHELL}
9

[local ~] ARRAY=(one two three)

[local ~] echo ${#ARRAY}
3

Transformations of variables

Substitution

${VAR:-WORD}

If VAR is not defined or null, the expansion of WORD is substituted; otherwise the value of VAR is substituted:

[local ~] echo ${TEST:-test}
test

[local ~] echo $TEST
 

[local ~] export TEST=a_string

[local ~] echo ${TEST:-test}
a_string

[local ~] echo ${TEST2:-$TEST}
a_string

This form is often used in conditional tests, for instance in this one:

[ -z "${COLUMNS:-}" ] && COLUMNS=80

It is a shorter notation for

if [ -z "${COLUMNS:-}" ]; then
	COLUMNS=80
fi

If the hyphen (-) is replaced with the equal sign (=), the value is assigned to the parameter if it does not exist:

[local ~] echo $TEST2


[local ~] echo ${TEST2:=$TEST}
a_string

[local ~] echo $TEST2
a_string

Using “+” instead of the exclamation mark sets the variable to the expansion of WORD; if it does not exist, nothing happens.

Removing substrings

To strip a number of characters, equal to OFFSET, from a variable, use this syntax:

${VAR:OFFSET:LENGTH}

The LENGTH parameter defines how many characters to keep, starting from the first character after the offset point. If LENGTH is omitted, the remainder of the variable content is taken:

[local ~] export STRING="thisisaverylongname"

[local ~] echo ${STRING:4}
isaverylongname

[local ~] echo ${STRING:6:5}
avery

${VAR#WORD}

and

${VAR##WORD}

These constructs are used for deleting the pattern matching the expansion of WORD in VAR. WORD is expanded to produce a pattern just as in file name expansion. If the pattern matches the beginning of the expanded value of VAR, then the result of the expansion is the expanded value of VAR with the shortest matching pattern (“#”) or the longest matching pattern (indicated with “##”).

If VAR is * or @, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.

If VAR is an array variable subscribed with “*” or “@”, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. This is shown in the examples below:

[local ~] echo ${ARRAY[*]}
one two one three one four

[local ~] echo ${ARRAY[*]#one}
two three four

[local ~] echo ${ARRAY[*]#t}
one wo one hree one four

[local ~] echo ${ARRAY[*]#t*}
one wo one hree one four

[local ~] echo ${ARRAY[*]##t*}
one one one four

The opposite effect is obtained using “%” and “%%”, as in this example below. WORD should match a trailing portion of string:

[local ~] echo $STRING
thisisaverylongname

[local ~] echo ${STRING%name}
thisisaverylong

Replacing parts of variable names

This is done using the

${VAR/PATTERN/STRING}

or

${VAR//PATTERN/STRING}

syntax. The first form replaces only the first match, the second replaces all matches of PATTERN with STRING:

[local ~] echo ${STRING/name/string}
thisisaverylongstring

That is it, i hope it was simple, thanks for joining me.
Enjoy !.

Comments are closed.