# 03. Variables and Expressions (Part 2)

## Expressions

• An expression is a series of operators and operands that evaluate to a single resulting value
• The operator is a symbol that represent a specific task the computer will do
• The operand is the data that the operator works on
• Example: In the expression n1 + n2
• n1 and n2 are the operands, + is the operator, and the expression will evaluate to a single number as a result
• There are 3 types of expressions
• Arithmetic: do calculation
• Conditional: compare values and evaluate to true or false
• File test: determine file status

## Arithmetic Expressionse

• For integers only
• Operators:

subtract

* multiply

/ divide (remember that it’s integer division, so you’ll get an integer as a result. For example: 3 / 2 => 1 as a result)

% modulus (calculates the remainder of a division. For example: 5 / 3 => 1 5 % 3 => 2)

++ Pre-increment (value in variable is incremented by 1 first, then use in any other evaluation)

Example: ++n * 3 means that n is incremented first, then the new n value is multiplied by 3

++ Post-increment (value in variable used in any necessary evaluation, then the value in the variable is incremented last)

Example: n++ * 3 means that the original n value is multiplied by 3 first, then n is incremented

– – [2 minus sign next to each other] Pre-decrement (value in variable is decremented by 1 first, then use in any other evaluation)

Example: --n * 3 means that n is decremented first, then the new n value is multiplied by 3

– – [2 minus sign next to each other] Post-decrement (value in variable n is used in any necessary evaluation first, then n is decremented by 1)

Example: n-- * 3 means that the original n value is multiplied by 3 first, then n is decremented

= assignment (store data value on the right side into variable on the left side)

*= multiply and assign (example: n *= 3 means n = n * 3)

/= divide and assign (example: n /= 3 means n = n / 3)

%= modulus and assign (example: n %= 3 means n = n % 3)

+= add and assign (example: n += 3 means n = n + 3)

-= subtract and assign (example: n -= 3 means n = n - 3)

• Operands can be:
• variables, as long as they store integer values
• constants
• There are 2 ways to evaluate an arithmetic expressions:
• let and (( ))
• If you don’t use one of the 2 ways above, the arithmetic evaluation will not be performed.
• For example: var=5+2 means that var will store the string “5+2”, not the number 7
• When evaluating arithmetic expression, order of operation is the same as in math: ( ) has highest precedence, then multiply and divide and modulus in order from left to right, then add and subtract in order from left to right, and assignment has the lowest precedence

## Arithmetic Evaluation with let

• Format: let “outputVar = expression”
• outputVar is the variable that stores the result of the evaluation
• expression is any arithmetic expression
• there is no \$ in front of any variable name
• the double quotes are required if you use space or ( ) in the expression
• Example:
• let “output1 = 5 + 2” use quotes due to space
• echo \$output 1 print 7
• let output2=6*3/2 no space or ( ), no quotes needed
• echo \$output 2 print 9
• let “output3=6*(3/2)” use quotes due to ( )
• echo \$output3 print 6
• Note that the order of operation is the same as in math, which explains the difference in output2 and output3

## Arithmetic Evaluation with (( ))

• Format: ((outputVar = expression))
• outputVar is the variable that stores the result of the evaluation
• expression is any arithmetic expression
• there is no \$ in front of any variable name
• Example:
• (( output1 = 5 + 2 )) space is ok
• echo \$output 1 print 7
• ((output2=6*3/2)) no space is ok
• echo \$output 2 print 9
• (( output3=6*(3/2) )) note order of operation due to ( )
• echo \$output3 print 6
• Note that the order of operation is the same as in math, which explains the difference in output2 and output3
• Between the 2 formats to evaluate arithmetic expressions, (( )) is more common

## Conditional Expressions

• Conditional expressions are evaluated to true or false, and are used for looping and selection statements
• The shell variable ? stores the exit status of a command that has just finished running
• Therefore, after a conditional expression you can use: echo \$? to see if the expression evaluates to true or false
• When an expression evaluates to true, the ? variable is 0 When an expression evaluates to false, the ? variable is 1
• This is because an exit status of 0 is considered success in Linux / Unix
• Conditional expressions are divided into:
• Relational expression to compare integers
• Relational expressions to compare strings
• Logical expressions: to group multiple logical conditions together

## Relational Expression for Integers

• There are 3 ways to evaluate integer relational expressions
• First way: using (( )) just like with arithmetic expressions
• Operators:

< less than

> greater than

<= less than or equal to

>= greater than or equal to

== equal to

!= not equal to

• Format: (( operand1 operator operand2))
• operand1 and operand2 can be a variable or a constant
• there is no \$ in front of the variable name
• Example:
• n=5
• (( n <= 5 )) n <= 5 is true
• echo \$? ? is 0
• Second way: use [[ ]]
• Operators:

-lt less than

-gt greater than

-le less than or equal to

-ge greater than or equal to

-eq equal to

-ne not equal to

• Format: [[ operand1 operator operand2 ]]
• operand1 and operand2 can be a variable or a constant
• there must be a space after [[ and a space before ]]
• Example:
• n=5
• [[ n -lt 5 ]] n -lt 5 is false
• echo \$? ? is 1
• Third way: use [ ]
• Operators are the same as with [[ ]]

-lt less than

-gt greater than

-le less than or equal to

-ge greater than or equal to

-eq equal to

-ne not equal to

• Format : [ operand1 operator operand2 ]
• operand1 and operand2 can be a variable or a constant
• there must be \$ in front of a variable name
• there must be a space after [ and a space before ]
• Example:
• n=5
• [ \$n -ge 5 ] n -ge 5 is true
• echo \$? ? is 0

## Relational Expression for Strings

• There are 2 ways to evaluate string relational expressions
• First way: use [ ]
• Operators:

= or == equal to (matching)

!= not equal to (not matching)

\< less than (comes before, based on ascii order)

\> greater than (comes after, based on ascii order)

-z zero length or empty string

All string compares are ASCII compare of character by character

• Format 1: [ operand1 operator operand2 ]
• operand1 and operand2 can be a variable or a constant
• there must be \$ in front of the variable name and it’s safer to have double quotes around the variable name
• there must be a space after [ and a space before ]
• Example:
• n=“/home/student”
• [ \$n != ~ ] n not equal home dir is true
• echo \$? ? is 0
• Second way: use [[ ]]
• Operators:

= or == equal to (matching)

!= not equal to (not matching)

< less than (comes before, based on ascii order)

> greater than (comes after, based on ascii order)

-z zero length or empty string

=~ matching a string with regular expression

• Format 1: [[ operand1 operator operand2 ]]
• operand1 and operand2 can be a variable or a constant
• there must be \$ in front of the variable name
• there must be a space after [[ and a space before ]]
• Example:
• n=“/home/student”
• [[ -z \$n ]] n is empty string will evaluate to false
• echo \$? ? is 1
• Between the 2 formats to evaluate string relational expression, [[ ]] is the most often used due to the operators that it takes
• For a thorough discussion between [ ] and [[ ]], see this link: http://mywiki.wooledge.org/BashFAQ/031

## Logical Expressions

• Logical expressions are used to evaluate conditions that are T or F
• Operators

! logical not: reverses true to false, and false to true

Example: if n is 2, then [[ ! \$n –gt 0 ]] is false

and [ ! \$n –gt 0 ] is false

and (( ! n > 0 )) is false

&& and -a

logical and: true only if both left and right sides are true, otherwise false if at least one side is false

T&&T => T T&&F => F F&&T => F F&&F => F

T –a T => T T –a F => F F –a T => F F –a F => F

&& is used with (( )) and [[ ]]

-a is used with [ ]

Example: if n is 2, m is 4, then (( m > n && n < 0 )) is false

and [[ \$m –gt \$n && \$n -lt 0 ]] is false

and [ \$m –gt \$n -a \$n -lt 0 ] is false

|| and -o

logical or: false only if both left and right sides are false, otherwise true if at least one side is true

T || T => T T || F => T F || T => T F || F => F

T –o T => T T –o F => T F –o T => T F –o F => F

|| is used with (( )) and [[ ]]

-o is used with [ ]

Example: if n is 2, m is 4, then (( m > n || n < 0 )) is true

and [[ \$m –gt \$n || \$n -lt 0 ]] is true

and [ \$m –gt \$n -o \$n -lt 0 ] is true

## File Test Expressions

• For evaluating file status
• Operators

-e exists

-f is a regular file

-d is a directory

-s has a non-zero size (not empty)

-w has write permission

-x has execute permission

-ot is older than

• Operands can be:
• Variables that contain a filename
• String constants that are filenames
• To evaluate file test expressions, use [ ] or [[ ]]
• there is no difference
• Examples using both formats

If fA is a symbolic link and is older than fB

[ -e fA ] evaluates to T

[[ -f fA ]] F

[ -d fA ] F

[[ -h fA ]] T

[ -s fA ] T

[[ -r fA ]] T

[ -w fA ] T

[[ -x fA ]] T

[ fA –nt fB ] F

[[ fA –ot fB ]] T

[[ fA –ef fB ]] F