Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Sometimes, a shell script must execute a set of commands if a condition is given and a
different one if it is not. This is what is called conditional execution of orders.
In this practice session, we study this structure and how logical expressions are evaluated that
will allow us to build more flexible and useful programs.
if is a shell keyword
That is, if is not an order, but a keyword that tells the interpreter to interpret what follows the
if as a conditional. The correct syntax for writing a conditional in shell script is:
if [ condition ] (1)
then
else
fi (2)
(1) The brackets [] and the spaces between them and the condition are mandatory.
It is a very common failure not to put space between the first bracket and the first character
It is also common to forget the space between the end of the condition and the last clasp ]
(2) The conditional structures in shell script start with the reserved word if and end with the
reserved word fi.
Strana 2
The condition within an if-then-else statement is always enclosed in square brackets and
between the brackets and the condition must exist a space, otherwise the interpreter will give
an error.
To build the conditions, values, parameter substitutions and operators are used.
For example:
[ -r ${1} ]
In shell programming, there are many operators that we can use to build our conditions.
The first eight are unary, that is, they only need an operand that is written after the operator:
[ file operator ]
The last two are binary, that is, they require two operands that are written one on each side of
the operator:
-r Check if what follows is the name of a file that exists and is readable.
-s Checks if the file exists and is not empty (its size is greater than zero).
-O Check if the file is owned by the person running the shell script.
-G Checks whether the file belongs to the group of the person running the shell script.
-nt It is placed between two file names and returns true if the first has a modification date
more recent than the second.
-ot Checks if the first file has a modification date older than the second.
They are all binary. That is, they apply to two arguments that are written one on each side of
the operator.
-eq Check if the two numbers that are passed as arguments are the same.
-ge Checked if the first number is greater than or equal to the second.
-gt Check if the first number is more strict than the second.
-lt Check if the first number is less strict than the second.
The first two are unary while the last two are binary. In addition, the last two ( < and > )
require double brackets so that they can be interpreted well, since they are also the symbols
that the interpreter uses to indicate redirection.
-z Indicates if the length of the string passed as an argument is zero (empty string).
< Indicates if the first string is smaller than the second. Does a lexicographic comparison (that
is, comparing character to character). For example, the goodbye chain is smaller than the hello
string.
Composite conditions:
Compound conditions can be used, for example checking at the same time if a file is readable
and executable. To do this, the logical operators & (and) and || (or) to separate two simple
conditions.
You can also use the unary operator ! to deny the result of a condition.
Important
As in any programming language, if in a shell script the syntax of the commands is not written
correctly, errors occur.
To learn how to program shell scripts, it is necessary to study the syntax and practice it with
various examples until you learn it.
Strana 3
One of the uses of conditionals in shell script programs is to check if all arguments have been
passed to the program. In those programs that require arguments, it is very important to verify
that the proper positional parameters have been passed, since a parameter that does not exist
is always replaced by the empty string and this could cause errors in the program.
Example: Write a shell script that receives two arguments and check if just two arguments
have been passed.
#!/bin/bash
# Author: Francisco de Asís Conde Rodríguez
then (2)
fi
(1) As we know from the previous session, the special parameter # contains the number of
positional parameters that were passed to the shell script when it was executed. Therefore if
we check if it is different from 2, we will have checked if our script has passed, or not, just two
arguments.
(2) The reserved word then has to be written on the line following the line where the reserved
word is. If you write on the same line, an error occurs when interpreting the line.
(3) Bleeding is optional, but if it is included, the code is much more readable.
As administrator of the operating system, in many cases you will have to make checks on files,
what permissions they have or to whom they belong, and based on these checks, perform
some administrative or other tasks.
Example: Write a shell script that receives an argument (the name of an executable file) and
check if that file is in the bin directory of the user that runs the shell script and is actually
executable. If it is not, you must write on the screen that the file does not exist, and if it is not
executable, you must write on the screen that it is not executable.
#!/bin/bash
if [ ${#} -ne 1 ]
then
exit
fi
if [ ! -e ${HOME}/bin/${1} ] (1)
then
echo The script does not exist: ${1}
else
if [ ! -x ${HOME}/bin/${1} ]
then
fi
fi
(1) The HOME variable contains the complete path of the base directory of the user that runs
the script. Note the importance of always using the keys {} in the replacement of
Strana 4
In shell script, all values are treated as strings unless otherwise indicated, therefore, it is very
important to know how to write conditionals in which the arguments of the conditions are
strings.
Example: Write a shell script that receives exactly two arguments and that they are different. If
two arguments are not written, or if they are the same, you must write an error on the screen.
#!/bin/bash
if [ ${#} -ne 2 ]
then
else
if [ ${1} = ${2} ]
then
fi
fi
Checking the equality of arguments is useful, for example, when renaming a file. In this case, if
the name of the file that is renamed and the new name that you want to give to the file are
the same, the rename command should not be executed.
Exercises
#!/bin/bash
if [ ! ${#} -eq 2 ]
then
fi
2) Write a shell script that checks if you have passed between two and four arguments,
in case you have not passed that number of arguments that you write
an error, and in case it has happened that you write them on the screen.
3) Write a shell script that receives exactly one argument, a username, and
check if a file called .profile exists in the base directory of that user.
If it does not exist, copy it from the /etc/skel directory in the user's directory and
4) Write a shell script that receives exactly one argument that is the name of a
directory. Then check if it already exists, and if it does not exist that believes it. By last,
5) Write a shell script that receives exactly two arguments that are strings of
characters and say if the first one is arranged alphabetically with respect to the second
or not.
6) The task of writing a new shell script requires several steps: check if the name
of the script already exists, write the file, give it execution permissions and copy it to the
directory ~/bin. Write a shell script that receives as an argument the name of a
new shell script that you want to write and simplify all those steps.
Note: The special parameter? returns the result of the last command (if executed