Sei sulla pagina 1di 6

Strana 1

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.

As in most programming languages, in the programming of shell scripts there is an if-then-else


structure, which are keywords or reserved from the interpreter of commands, and which allow
to program the 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 it is written to a terminal type -a if, the terminal responds:

fconde @ fconde-VirtualBox: ~ $ type -a if

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

sentences if true condition

else

sentences if false condition

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

of the condition. For example, when executing:

if [-d ${HOME}/bin] (The first bracket [ is attached to -d with no space)

the interpreter gives the error:

[-d: the order was not found

It is also common to forget the space between the end of the condition and the last clasp ]

For example when executing:

if [ -d $ {HOME} / bin] (The last bracket ] is pasted without space to bin)

the interpreter gives the error:

bash: [: missing a `] '

(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} ]

is a syntactically well-constructed condition that checks whether the value of positional


parameter 1 is the name of a file that exists and is readable (readable).

In shell programming, there are many operators that we can use to build our conditions.

Operators to apply to files:

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:

[ file1 operator file2 ]

-r Check if what follows is the name of a file that exists and is readable.

-x Checks if the file exists and is executable.

-h Check if the file exists and it is a symbolic link.

-d Checks if the file exists and is a directory.

-s Checks if the file exists and is not empty (its size is greater than zero).

-e Check if the file exists.

-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.

Operators to apply to numbers:

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.

-ne Check if the two numbers are different.

-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.

-Verifies if the first number is less than or equal to the second.

-lt Check if the first number is less strict than the second.

Operators to apply to character strings:

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).

-n Indicates if the length of the string is greater than zero.

= Check if the two strings are the same.

! = Check if the two character strings are different.

< 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.

> Indicates if the first string is greater than the second

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.

[ -r ${file} ] && [ -x ${file} ]

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

Check if all arguments have been passed

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

# Description: Check if the script has passed

# just two arguments.

if [ ! ${#} -eq 2 ]  (1)

then  (2)

echo "Error, ${#} argument (s) have been passed"  (3)

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.

Check whether or not there is a file

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

#Author: Francisco de Asís Conde Rodríguez

#Description: Check if a name is passed as

#argument corresponds to a program

#executable located in the directory ~/bin

if [ ${#} -ne 1 ]

then

echo "Error, an argument must be passed"

exit

fi

if [ ! -e ${HOME}/bin/${1} ]  (1)

then
echo The script does not exist: ${1}

else

if [ ! -x ${HOME}/bin/${1} ]

then

echo ${1} is not an executable

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

parameters. If it were not used, the substitution ${HOME}/bin/${1} would be impossible.

Strana 4

Compare character strings

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

#Author: Francisco de Asís Conde Rodríguez

#Description: Check if the two arguments are

#dan are the same.

if [ ${#} -ne 2 ]

then

echo "Error, two arguments have not been given"

else

if [ ${1} = ${2} ]

then

echo "Error, the arguments are the same"

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

1) Rewrite the shell script:

#!/bin/bash

#Author: Francisco de Asís Conde Rodríguez

#Description: Check if the script has passed

#just two arguments.

if [ ! ${#} -eq 2 ]

then

echo "Error, ${#} argument(s) passed"

fi

to do the same check, but using other operators.

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

give him permissions -rw-r-r--

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,

whether it existed previously or not, that gives drwx permissions ------

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

with or without errors).

Potrebbero piacerti anche