Linux test command (test conditions)
The test command is a great tool for testing conditions. Based on the return variable of the test command, programming logics can be set up to execute something if a condition is satisfied or not.
It can test conditions on files, permissions, texts, numbers, and even through expressions and provide the result through the return variable $? .
In this example, the test command checks that 1 is less than 2 (-lt = less than - less than):
Since the return variable was 0, the number 2 is less than 1.
In this other example, it tests with the “-d” if the file /usr/src is a directory:
0
The most common test command options are:
**Option** | **What Is It** | **For Example** |
-d /directory | Checks if a file is a directory and that it exists | $ test -d /etc |
-e file | Checks if a file exists regardless of its type | $ test -e /etc/passwd |
-f file | Checks whether a file exists and whether it is common | $ test -f /etc/passwd |
-z file | Check if the file is empty | $ test -z /etc/groups |
-n “$ variable” | Check if the size of a text is greater than zero | $ test -n “$BOOK” |
-s file | Checks if a file exists and that its size is greater than zero | $ test -s /etc/passwd |
s1 = s2 | Checks if a text is the same as another | $ test “$BOOK” = “Linux Certification” |
s1! = s2 | Check if a text is different from another | $ test “$BOOK”! = “Linux Certification” |
x -eq y | Checks if a number **x** equals **y** | $ VAR=10; test $VAR -eq 10 |
x -gt y | Check if a number **x** is greater than **y** | $ VAR=10; test $ VAR -gt 9 |
x -lt y | Check if a number **x** is smaller than **y** | $ VAR=10; test $VAR -lt 11 |
x -ne y | Checks if a number **x** is not equal to **y** | $ VAR=10; test $VAR -ne 11 |
x -ge y | Check if a number **x** is greater than or equal to **y** | $ VAR=10; test $VAR -ge 9 |
x -le y | Check if a number **x** is less than or equal to **y** | $ VAR=10; test $VAR -le |
expression -a expression | Check if both expressions are true | $ test 10 -ge 9 -a 22 -gt 10; echo $? |
expression -o expression | Check if an OR expression are true | $ test 10 -ge 11 -o 22 -gt 10; echo $? |
file1 -nt file2 | Checks if file1 was modified after file2 (newer) | $ test file1 -nt file2 |
file1 -ot file2 | Checks if file1 was modified before file2 (older) | $ text file1 -ot file2 |
-r file | Checks if the file is allowed to read | $ test -r file |
-w file | Checks if the file has writing permission | $ test -w file |
-x file | Checks if the file has permission to execute | $ test -x file |
-The file | Checks whether you are the owner of the file | $ test -The file |
Use of [ ] instead of “test”
The test command can be abbreviated with brackets []. Note that there must be a space between the expression and the brackets:
|| and && operators
The operators (pipe pipe) II and && are used to verify whether the expression on the right returns true or false.
The && operator checks whether something on your right is true, and therefore executes the command on your left.
In this example, we force return true with the “true” command, which will always return true:
If we use the “false” command, which always returns false, the && operator will not execute the command on the left:
Operator II checks if something on your right is false, and therefore executes the command on your left.
In this example, we force return true with the true command. In this case, the II will not execute anything.
By the way, forcing a false return with the false command, II executes the echo command:
The && and II operators can also be used together:
In this case it will return YES because 100 is greater than 99.
Flow control with if (se)
Flow controls (if) are commands that test some alternatives and, according to the result, execute commands.
The logic of the if command is “if this is true, do this, if not, do that”. See the example:
In this example the if tests whether the content of the return variable $? It’s 0. If so, execute the echo command “The command completed successfully…”. If the condition is false, execute the command echo “The Command failed.”.
Unlike other languages, if tests a command and not a condition. Therefore, we must use the test command together with the if command. It is generally written using the shortcut of brackets [ ] for the test command.
Flow control with case
The case is an intelligent way to compare the value of something with various standards.
If an occurrence is positive, it allows commands to be executed.
Each case is an expression that corresponds to a pattern.
The ”)” operator ends a list of patterns and starts a list of commands.
What separates one pattern from another is ”;;”.
At the end of the case, you must finish with the esac instruction (case on the contrary).
Example of a script that, depending on the user’s UID, prints a different message:
If the value of the ID variable is 0, it will print a congratulations message. If it is equal to 1000, print “you are Uira”. If it’s between 1001 and 1009, print “You are another user.
If executed with the user uira, who has a UID equal to 1000:
If run as root:
The case is better than using the “if” command several times to compare something with various patterns.
Loops with the for command
$ for something; do command; command2; done
The shell has structures for testing conditions and executing certain program sequences several times (loop), until the tested condition is satisfied.
The three commands that enable this are for (until some condition), while (as long as it is true) and until (as long as it is false).
The for command allows loops to be made so that one or more commands are executed until a given variable goes through all the values in a given list.
Here’s a simple example:
The same command can be written on a single line:
See another example using a list in a file:
You can now use for to execute several commands for each filename in the list list_files.txt:
This loop assigns each line of the list_files.txt file to the $i variable.
The expression $(command) generates a list with the result of the command. It has the same effect as using the command between classes: **command**
.
It then executes the commands to rename and move the files until the list is complete.
Now a slightly more complex example, using for with if:
In this line, the result of the ls -1 command is placed in the variable $i; then each line of the variable $i is tested to find out if it is a file; if true, a sentence will be displayed and, if false, another sentence will be displayed.
Loops with the while command
$ while [expression]; of the command; command; done
While continuously tests an expression until an expression has a return variable equal to zero or true.
In this example, the variable $i gains an initial value equal to zero.
As long as (while) the test command condition represented by [ ] returns zero (true), the loop will continue to execute.
In the loop, the variable $i is increased until $i reaches the condition of not being less than 4:
account 0
account 1
account 2
account 3
The while must have a satisfied exit condition, otherwise it will be in an infinite loop.
Loops with the until command
The until command is the opposite of the while command, but it executes something while the test is false, or with non-zero values.
Its syntax is:
Example:
counter=0
until [$counter -gt 3]
do
echo Counter: $counter
(counter++))
done
When executed:
Counter: 0
Counter: 1
Counter: 2
Counter: 3
Until is useful for making a script wait until a command no longer returns an error, since it is only executed if the test return is different from zero.
A program’s zero exit code generally indicates that it ran successfully.
In this example, the until command is used to wait until the host is able to ping IP 8.8.8.8. When the ping command succeeds in pinging host 8.8.8.8, it will return zero, causing the processing to leave the loop: