if test_command
then
commands
[else
commands
]
fi
The if statement tests the status returned by the test_command and transfer controls based on that
status. The returned status considered true is the error code returned by the test_command is 0,
and it's considered to be false if it's not 0. It can be any command that returns a value to the shell, but
most often the special built-in command test is used.
| Expression | Returns true when | |
| Compare strings | ||
| [-n] STRING | the length of STRING is nonzero | |
| -z STRING | the length of STRING is zero | |
| STRING1 = STRING2 | the strings are equal | |
| STRING1 != STRING2 | the strings are not equal | |
| Compare integers | ||
| INTEGER1 -eq INTEGER2 | INTEGER1 is equal to INTEGER2 | |
| INTEGER1 -ge INTEGER2 | INTEGER1 is greater than or equal to INTEGER2 | |
| INTEGER1 -gt INTEGER2 | INTEGER1 is greater than INTEGER2 | |
| INTEGER1 -le INTEGER2 | INTEGER1 is less than or equal to INTEGER2 | |
| INTEGER1 -lt INTEGER2 | INTEGER1 is less than INTEGER2 | |
| INTEGER1 -ne INTEGER2 | INTEGER1 is not equal to INTEGER2 | |
| Test files | ||
| FILE1 -nt FILE2 | FILE1 is newer (modification date) than FILE2 | |
| FILE1 -ot FILE2 | FILE1 is older than FILE2 | |
| -d FILE | FILE exists and is a directory | |
| -e FILE | FILE exists | |
| -f FILE | FILE exists and is a regular file | |
| -L FILE | FILE exists and is a symbolic link | |
| -r FILE | FILE exists and is readable | |
| -s FILE | FILE exists and has a size greater than zero | |
| -w FILE | FILE exists and is writable | |
| -x FILE | FILE exists and is executable | |
if test $# -eq 0
then
echo "You have to provide at least one argument!"
exit
fi
In this example please pay attention to the new line after the 0 in the test command. We cannot put
then on the same line, because if we do it'll be treated as an argument of the test command.
In other words, we need to separate the test commands with its arguments from the then keyword.
To do that we need to either put a new line or a semicolon symbol, which also separates one command from the other.
if test -f "$1"; then
echo "$1 is a regular file in the working directory"
else
echo "$1 is NOT a regular file in the working directory"
fi
We can also use combinations of logical conditions using logical operators AND (option -a) and
OR (option -o)
if test $# -gt 0 -a -r "$1"
then
echo File '$1' has `cat $1 | wc -l` lines
fi
We can also use parenthesis for difficult expressions and logical NOT, we need to use exclamation mark for this one.
Note: Beware that parentheses need to be escaped (e.g., by backslashes) for shells.
if test $# -gt 0 -a \( -f "$1" -o -d "$1" \) ; then echo "$1 is a regular file or a directory" fiThere is a shortcut for the test command. Instead of using test with the expression as an argument we can put the same expression inside the square brackets. It looks more like usual languages
if [ $# -gt 0 -a \( -f "$1" -o -d "$1" \) ]; then echo "$1 is a regular file or a directory" fiPlease note that the brackets must be surrounded by spaces or tabs.
case test_string in
pattern_1)
commands_1
;;
pattern_2)
commands_2
;;
...
pattern_n)
commands_n
;;
esac
where patterns is an expression that may contain the following special symbols
| Symbol | Description |
| * | Matches any string of characters. |
| ? | Matches any single character. |
| [...] | Defines a character set. Any character enclosed within brackets are tried, one at a time, in an attempt to match a single character. A hyphen between two characters specifies a range of characters. |
| | | Separates alternative choices that satisfy a particular branch of the case statement. |
case "$1" in
start)
echo "Starting the program"
;;
stop)
echo "Stopping the program"
;;
restart)
echo "Restarting the program"
;;
*)
echo -e "Use:\n\t$0 start|stop|restart"
;;
esac
for loop_index in argument_list do commands doneThis construction assigns the value of the first argument in the argument_list to the variable loop_index and executes the commands between do and done. Then it assigns the next value in the list ..., etc. Example:
# dirlist
for fl in *
do
if [ -d $fl ]; then
echo $fl
fi
done
We can also assign the list manually:
num=1 echo Your choice: for item in file edit search format insert tools tags options help do echo " $num: $item" num=`expr $num + 1` done read choiceor run the same commands for each script argument
for a in $@ do echo $a done
for loop_index do commands done
We can also use C-like syntax with the for loop:
N=10 for((i=0;i<N;i++)) do echo $i donePlease pay attention that we must have double parenthesis and we do not need a leading dollar sing with N.
while test_command do commands doneand
until test_command do commands doneThe while loop keeps repeating the commands while the test_command returns true value (that is, zero error code), and the until loop keeps repeating while the test_command returns false; that is, it works until it becomes true.
Let's take a look at the useful script locktty from the A Practical Guide to Red Hat Linux 8 by Mark Sobell.
#!/bin/bash
trap '' 1 2 3 18
stty -echo
echo -n "Your keyword: "
read kw_one
echo
echo =n "Confirmation: "
read kw_two
if [ "$kw_one" = "$kw_two" ]; then
kw_two=
tput clear
until [ "$kw_one" = "$kw_two" ]
do
echo -e "\nEnter the keyword to activate: \c"
read kw_two
done
else
echo -e "\nYour keywords do not match!"
fi
echo
stty echo
This script asks the user for a password and the confirmation, and then refuse to terminate until user enters the password
again. Some short explanations: