68
Paolo Santinelli / Lorena Marassi AS 2015/2016 Sistemi e Reti ITIS E. Fermi, Modena 1 /68 Variables a variable is created simply just using it (no need for variables declaration). A variable may be assigned to by a statement of the form: A variable is an entity that stores a values denoted by a name name=[value] where name is the name of the variable and value is a string. Note that in an assignment, there must be no spaces between the variable name, the equals sign, and the value. The shell does not care about the type of data assigned to a variable: it treats them all as strings (but she can treat them as number, when necessary) and doesn't make any formal distinction between variables and constants If value is not given, the variable is assigned the null string; once a variable is set, the only way to come back to this condition is by using the unset built in command definition and assignment

Variables - ITIS E. Fermicaronte.fermi.mo.it/edu/Members/prof.sanpol/sistemi-e-reti/linux/... · ITIS E. Fermi, Modena Paolo Santinelli / Lorena Marassi Sistemi e Reti AS 2015/2016

Embed Size (px)

Citation preview

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 1 /68

Variables

a variable is created simply just using it (no need for variables declaration).

A variable may be assigned to by a statement of the form:

A variable is an entity that stores a values denoted by a name

name=[value]

where name is the name of the variable and value is a string. Note that in an assignment, there must be no spaces between the variable name, theequals sign, and the value.

The shell does not care about the type of data assigned to a variable: it treats them all as strings (but she can treat them as number, when necessary) and doesn't make any formal distinction between variables and constants

If value is not given, the variable is assigned the null string; once a variable is set, the only way to come back to this condition is by using the unset built in command

definition and assignment

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 2 /68

Variables

To see the content of a variable, we can use the echo command and the parameter expansion (see later) to access the variable's content:

echo $[variable name]

Rules about variable names:Variable names may consist of alphanumeric characters (letters and numbers) and underscore characters;The first character of a variable name must be either a letter or an underscore;Spaces and punctuation symbols are not allowed;

output and variables name

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 3 /68

Variables

a=z # Assign the string "z" to variable a.b="a string" # Embedded spaces must be within quotes.c="a string and $b" # Other expansions such as variables can

# be expanded into the assignment.d=$(ls -l) # Results of a command.e=$((5 * 7)) # Arithmetic expansion.f="\t\ta string\n" # Escape sequences such as tabs and

# newlines.

# Multiple variable assignments may be done on a single line:#a=5 b="a string"

assignment examples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 4 /68

Variablessystem variables

System variables are created and maintained by the shell itself. This type of variable is generally defined in CAPITAL LETTERS. You can configure aspects of the shell by modifying system variables such as PS1, PATH,... etc.

To see all system variables, use the set or printenv command.

Some of the system variables are:

System variable meaning

HOSTNAME the name of your computer

HISTSIZE the number of commands to remember in the command history

HOME the home directory of the current user

PATH the search path dor command: it is a colon separated list of directories in which the shell looks for commands

USER your username

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 5 /68

Expansion

Each time you type a command line and press the enter key, bash can perform several processes upon the entered text before it carries out the required command. These processes are called expansions.

With expansion, when you enter something, this can be expanded into something else before the shell acts upon it.

There are six kind of expansion: Pathname expansion;Tilde Expansion;Brace expansion;Parameter expansion;Command substitution;Arithmetic expansion;

definition

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 6 /68

On Linux, the shell is responsible for interpreting and expanding globs (i.e. the "filename wildcards" we've already encountered, * and ?)

A called program will never see the glob itself; it will only see the result of the expansion (that is the list of files whose name is included in the wildcards) as its arguments:

paolo@ubuntu-server:~/source$ echo *client.c resolv-name.c server.cpaolo@ubuntu-server:~/source$

paolo@ubuntu-server:~/source$ for file in * ; do echo $file; done client.cresolv-name.cserver.cpaolo@ubuntu-server:~/source$

Expansionpathname expansion (globbing)

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 7 /68

the tilde character (“~”) has a special meaning. When used at the beginning of a word, it expands into the name of the home directory of the named user, or if no user is named, the home directory of the current user:

paolo@ubuntu-server:~/source$ echo ~/home/paolopaolo@ubuntu-server:~/source$

paolo@ubuntu-server:~/source$ echo ~giovanni /home/giovannipaolo@ubuntu-server:~/source$

Expansiontilde expansion

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 8 /68

Brace expansion is a mechanism by which arbitrary strings may be generated. Multiple text strings can be created from a pattern containing braces:

Patterns may contain:a leading portion called a preamble;a trailing portion called a postscript;

Patterns may not contain embedded whitespace.

paolo@ubuntu-server:~/source$ echo front_{A,B,C,D}_backfront_A_back front_B_back front_C_back front_D_backpaolo@ubuntu-server:~/source$

comma-separated list of strings

preamble

postscript

Expansionbrace expansion

Braces may contain either:a comma-separated list of strings;a range of integers or single characters;

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 9 /68

#range of integerspaolo@ubuntu-server:~/source$ echo Number_{1..5}Number_1 Number_2 Number_3 Number_4 Number_5paolo@ubuntu-server:~/source$

#range of zero padded integerspaolo@ubuntu-server:~/source$ echo {01..10}01 02 03 04 05 06 07 08 09 10paolo@ubuntu-server:~/source$

#range of letters in reverse orderpaolo@ubuntu-server:~/source$ echo {z..a}z y x w v u t s r q p o n m l k j i h g f e d c b apaolo@ubuntu-server:~/source$

#nested brace expansionpaolo@ubuntu-server:~/source$ echo a{A{1,2},B{3,4}}baA1b aA2b aB3b aB4bpaolo@ubuntu-server:~/source$

Expansionbrace expansion examples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 10 /68

paolo@ubuntu-server:~/disk_space/dir/dir_2$ mkdir {2010..2011}-{01..12}paolo@ubuntu-server:~/disk_space/dir/dir_2$ ls2010-01 2010-04 2010-07 2010-10 2011-01 2011-04 2011-07 2011-102010-02 2010-05 2010-08 2010-11 2011-02 2011-05 2011-08 2011-112010-03 2010-06 2010-09 2010-12 2011-03 2011-06 2011-09 2011-12paolo@ubuntu-server:~/disk_space/dir/dir_2$

The most common application of brace expansion is to create lists of files or directories:

Expansionbrace expansion examples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 11 /68

parameter expansioncommand substitutionarithmetic expansion

parameter expansion reveal the contents of variables

command substitution allows to use the output of a command as an expansion

the shell allows arithmetic to be performed by expansion. The shell prompt is used as a calculator

The ‘$’ character introduces:

Expansionother expansions

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 12 /68

Parameter expansion reveal the contents of variables. The name of the variable to be expanded may be enclosed in braces, which are optional but serve to make unambiguous the name itself when it is followed by other characters.

#variable creation and assignmentpaolo@ubuntu-server:~$ VAR=contentspaolo@ubuntu-server:~$

#parameter expansionpaolo@ubuntu-server:~$ echo $VARcontentspaolo@ubuntu-server:~$

#parameter expansion enclosed in bracespaolo@ubuntu-server:~$ echo ${VAR} contentspaolo@ubuntu-server:~$

#parameter expansion with appended stringpaolo@ubuntu-server:~$ echo ${VAR}=valuecontents=valuepaolo@ubuntu-server:~$

Expansionparameter expansions

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 13 /68

Command substitution allows the output of a command to replace the command itself.

Command substitution occurs when a command is enclosed as follows:$(command) or `command`

#command substitution examplespaolo@ubuntu-server:~/scripts$ echo $(ls)01_show-pos-param 02_show-all-arguments 03_if_file-state-eval 04_while-loop paolo@ubuntu-server:~/scripts$

paolo@ubuntu-server:~/scripts$ ls -l $(which rm) -rwxr-xr-x 1 root root 60160 Mar 24 2014 /bin/rmpaolo@ubuntu-server:~/scripts$

Expansioncommand substitution

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 14 /68

Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result

The format for arithmetic expansion is: $(( expression ))

#arithmetic expansion examplespaolo@ubuntu-server:~$ echo $((4+5))9paolo@ubuntu-server:~$

paolo@ubuntu-server:~$ A=10paolo@ubuntu-server:~$ echo $(($A+5)) 15paolo@ubuntu-server:~$

paolo@ubuntu-server:~$ echo $(( $(($A+5))*3 )) 45paolo@ubuntu-server:~$

All tokens in the expression undergo parameter expansion, command substitution, and quote removal. Arithmetic expansions may be nested

Expansionarithmetic expansion

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 15 /68

Word Splitting

Word splitting is the mechanism used by the shell to separate the various elements entered in the command line: multiple words separated by one or more delimeter characters become separate items.

This behavior is configured by a shell variable named IFS (Internal Field Separator): the shell performs word splitting on the input using each character contained in $IFS ad a delimeter.

The default value of IFS contains:the space;the tab ('\t');the newline character ('\n');

#word splitting removes extra whitespaces paolo@ubuntu-server:~/scripts$ echo this is a testthis is a testpaolo@ubuntu-server:~/scripts$

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 16 /68

Quoting

Quoting is a mechanism to suppress: word splitting; selected unwanted expansions.

#word splitting suppressionpaolo@ubuntu-server:~/scripts$ "this is a test"this is a testpaolo@ubuntu-server:~/scripts$

In the example above, word-splitting is suppressed: by quoting the embedded spaces are not treated as delimiters but they become part of the argument. In this way the command line contains a command followed by a single argument.

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 17 /68

Quoting

type of quotes

Double quotes“ “

Single quotes' '

● all the special characters are treated as ordinary characters● parameter expansion, arithmetic expansion, and command substitution are still carried out

they suppress all expansions

Quoting can also suppress unwanted expansions:

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 18 /68

Quoting

Double quotes can be used to cope with filenames containing embedded spaces.

word-splitting would cause this to be treated as two separate arguments rather than the desired single argument:

paolo@ubuntu-server:~/scripts$ ls -l two words.txtls: cannot access two: No such file or directoryls: cannot access words.txt: No such file or directorypaolo@ubuntu-server:~/scripts$

By using double quotes the word-splitting is stopped and we get the desired result:

paolo@ubuntu-server:~/scripts$ ls -l "two words.txt"l-rw-rw-r-- 1 me me 18 2008-02-20 13:03 two words.txtpaolo@ubuntu-server:~/scripts$

double quotes

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 19 /68

Quoting

Double quotes: parameter expansion, arithmetic expansion, and command substitution still work:

paolo@ubuntu-server:~/scripts$ echo "$USER $((2+2)) $(cal)" paolo 4 December 2014 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 paolo@ubuntu-server:~/scripts$

parameter expansion arithmetric expansion

command substitution

double quotes

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 20 /68

Quoting

Single quotes: they suppress all expansions

#no quotes: everything workpaolo@ubuntu-server:~/source$ echo text ~/ {a,b} $(echo foo) $((2+2)) $USER text /home/paolo/ a b foo 4 paolopaolo@ubuntu-server:~/source$

#double quotes: pathname, tilde and brace expansion are suppressed; parameter and arithmetic expansion and command substitution still work paolo@ubuntu-server:~/source$ echo "text ~/ {a,b} $(echo foo) $((2+2)) $USER" text ~/ {a,b} foo 4 paolopaolo@ubuntu-server:~/source$

#single quotes: all expansions are suppressedpaolo@ubuntu-server:~/source$ echo 'text ~/ {a,b} $(echo foo) $((2+2)) $USER' text ~/ {a,b} $(echo foo) $((2+2)) $USERpaolo@ubuntu-server:~/source$

single quotes

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 21 /68

Shell Scripts

In the simplest terms, a shell script is a text file containing a series of commands: the shell reads this file and carries out the commands as though they have been entered directly on the command line

this means that the shell is: a powerful command line interface to the system; a scripting language interpreter

definitions

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 22 /68

Shell Scripts

To realize a running shell script we need:

1. Write the script, using a text editor such as vim, nano,...

2. Make the script executable, for example by using one of the commands:● chmod a+x [script-name]

ο

a script executable by everybody;● chmod u+x [script-name]

ο

a script executable only by the owner.please note that in order to be executable, the script must also be readable.

3. Put the script in the right place● you can always execute the script specifying the script pathname, for example: ./scriptname

ο

if the script is in current working directory● put the script somewhere the shell can automatically find it: the shell searches

certain directories for executable files when no explicit pathname is specified. For maximum convenience, we will place our scripts in these directories

writing a script

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 23 /68

Shell Scripts

The system searches a list of directories each time it needs to find an executable program, if no explicit path is specified. The list of directories is held within an environment variable named PATH. The PATH variable contains a colon-separated list of directories to be searched:

the bin sub-directory of the user's home directory is the right place for script of personal use. In the Ubuntu based distribution, when this directory is created, it is automatically added to the system PATH at the successive user login

(otherwise, to add a directory to the PATH variable, see the Linux Command Line, pag 357)

writing a script

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 24 /68

Shell Scripts

Following the tradition, our first script will be “Hello World”:

the first script

#!/bin/bash

#primo esempio di script

echo “Hello World” #ciao mondo

The #! character sequence is a special construct called a shebang.The shebang is used to tell thesystem the name of the interpreter that should be used to execute the script that follows.Every shell script should include this as its first line.

Except for the first line, the # character introduces a comment. Everything after the # symbol is simply ignored by the shell

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 25 /68

Positional Parameters

Positional parameters provide the ability to accept and process command line options and arguments:

the shell provides a set of variables that contain the individual words on the command line;the variables are named 0 through 9.

#/bin/bash#echo "\$0 = $0\$1 = $1\$2 = $2\$3 = $2\$4 = $4\$5 = $5\$6 = $6\$7 = $7\$8 = $8\$9 = $9"

this script display the values of the positional parameters:

● the first parameter $0 always contains the pathname of the script itself;● the parameters from $1 to $9 contain the strings entered at the command line after the command itself, in the same order

NB the '\' character at the beginning of each line is for escaping the first (single) character $ without applying expansion to it

definitions

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 26 /68

#/bin/bash#echo "Number of arguments: $#"echo "\$0 = $0\$1 = $1\$2 = $2\$3 = $2\$4 = $4\$5 = $5\$6 = $6\$7 = $7\$8 = $8\$9 = $9"

The variable $# yields the number of arguments actually typed on the command line

Positional Parametersnumber of positional parameter

Even if probably isn't a good idea to consider script which require so many parameters, the shell effectively provide more than nine positional parameters. To specify a number greater than nine, surround the number in braces. For example ${10}, ${55}, ${211}, and so on

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 27 /68

#/bin/bash#count=1

while [[ $# -gt 0 ]]; do echo "Argument $count = $1" count=$((count + 1)) shiftdone#

The shift command causes all the parameters to “move down one” each time it is executed. In fact, it is possible to get by with only one parameter

Each time shift is executed, the value of $2 is moved to $1, the value of $3 is moved to $2 and so on. The value of $# is also reduced by one.

Positional Parametersgetting access to many arguments

in the example, all parameters are accessed using a while loop (see later) in combination with the shift command

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 28 /68

Exit Status

Commands issue a value to the operative system when they terminate. This value, is an integer in the range of 0 to 255, indicates the success or failure of the command’s execution:

zero indicates success;other value indicates failure;

$? is the parameter provided by the shell that can used to examine the exit status

#example 1: the command is correct, the exit status is 0paolo@ubuntu-server:~$ ls -d /usr/bin//usr/bin/paolo@ubuntu-server:~$ echo $?0

#example 2: the command is not correct, the exit status is

ζ

0paolo@ubuntu-server:~$ ls -d /usr/binn/ls: cannot access /usr/binn/: No such file or directorypaolo@ubuntu-server:~$ echo $? 2

possible values

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 29 /68

paolo@ubuntu-server:~$ true paolo@ubuntu-server:~$ echo $?0

paolo@ubuntu-server:~$ falsepaolo@ubuntu-server:~$ echo $?1paolo@ubuntu-server:~$

Exit Statusthe true and false commands

The shell provides two commands with a definite exit status:

the true command always executes successfully;the false command always executes unsuccessfully;

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 30 /68

Flow Control -if-Branching with if

The if statement has the following syntax:

if commands; thencommands

[elif commands; thencommands...]

[elsecommands]

fi

where commands is a list of commands

X=5

if [ $x -eq 5 ]; thenecho "x equals 5."

elseecho "x does not equal 5."

fi

example: check if x value is equal to 5 or not

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 31 /68

when a list of commands follows if, the last command in the list is evaluated

paolo@ubuntu-server:~$ if true; then echo "It's true."; fiIt's true.

paolo@ubuntu-server:~$ if false; then echo "It's true."; fipaolo@ubuntu-server:~$

paolo@ubuntu-server:~$ if false; true; then echo "It's true"; fiIt's true

paolo@ubuntu-server:~$ if true; false; then echo "It's true"; fi paolo@ubuntu-server:~$

Flow Control -if-Branching with if

some example of if with true and false:

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 32 /68

the command used most frequently with if is test, which performs a variety of checks and comparisons.

The test command has some equivalent forms:

test expression;

[ expression ];

[[ expression ]], (modern version, it supports regular expressions);

(( )), (modern version, it operates on integer, see cap 34, The Linux Command Line);

where expression is an expression that is evaluated as either true or false: the test command returns an exit status of zero when the expression is true and an exit status of one when the expression is false;

File Expressions

String Expressions

Integer Expressions

expression

Flow Control -if-test

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 33 /68

The following expressions are used to evaluate the status of files:

Expression Is True If:---------------------------------------------------------------------------file1 -ef file2 ......file1 and file2 have the same inode numbers (the two

file names refer to the same file by hard linking).file1 -nt file2 ......file1 is newer than file2.file1 -ot file2 ......file1 is older than file2.-b file...............file exists and is a block-special (device) file.-c file...............file exists and is a character-special (device) file.-d file...............file exists and is a directory.-e file...............file exists.-f file...............file exists and is a regular file.-g file...............file exists and is set-group-ID.-G file...............file exists and is owned by the effective group ID.-k file...............file exists and has its “sticky bit” set.-L file...............file exists and is a symbolic link.-O file...............file exists and is owned by the effective user ID.-p file...............file exists and is a named pipe.-r file...............file exists and is readable (has readable permission

for the effective user)-s file...............file exists and has a length greater than zero.-S file...............file exists and is a network socket.

Flow Control -if-file expression

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 34 /68

Expression Is True If:----------------------------------------------------------------------------t fd.................fd is a file descriptor directed to/from the

terminal. This can be used to determine whetherStandard input/output/error is being redirected.

-u file...............file exists and is setuid.-w file...............file exists and is writable (has write permission for

the effective user).-x file...............file exists and is executable (has execute/search

permission for the effective user).

Flow Control -if-file expression

#!/bin/bash

if [ ! -f $1 ]; thenecho “$1: no such file”exit 1

fi

cat $1

example:script usage: scriptname [filename]the script test for the existence of the file whose name is passed as the first positional parameter.If the file doesn't exist the script display an error message and return an exit status of 1, otherwise it shows the file's content

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 35 /68

The following expressions are used to evaluate strings:

Expression Is True If:---------------------------------------------------------------------------string................string is not null.-n string.............The length of string is greater than zero.-z string.............The length of string is zero.string1 = string2.....string1 and string2 are equal. Single or doublestring1 == string2....equal signs may be used, but the use of double

equal signs is greatly preferred.string1 != string2....string1 and string2 are not equal.string1 > string2.....string1 sorts after string2.string1 < string2.....string1 sorts before string2.

Warning: the > and < expression operators must be quoted (or escaped with a backslash) when used with test. If they are not, they will be interpreted by the shell as redirection operators, with potentially destructive results.

Flow Control -if-string expression

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 36 /68

Flow Control -if-string expression

#!/bin/bash

if [ "$1" '<' "$2" ]; thenecho "$1 $2"

elseecho "$2 $1"

fi

example:script usage: scriptname [string1] [string2]the script accept two string passed as positional parameters and display them in alphabetical order

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 37 /68

The following expressions are used with integers:

Expression Is True If:---------------------------------------------------------------------------integer1 -eq integer2.....integer1 is equal to integer2.integer1 -ne integer2.....integer1 is not equal to integer2.integer1 -le integer2.....integer1 is less than or equal to integer2.integer1 -lt integer2.....integer1 is less than integer2.integer1 -ge integer2.....integer1 is greater than or equal to integer2.integer1 -gt integer2.....integer1 is greater than integer2.

Recent versions of bash include a compound command that acts as an enhanced replacement for test. It uses the following syntax: [[ expression ]]where, like test, expression is an expression that evaluates to either as true or false.

The [[ ]] command is very similar to test (it supports all of its expressions), but adds an important new string expression: string1 =~ regexwhich returns true if string1 is matched by the extended regular expression regex.

Flow Control -if-integer expression

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 38 /68

Flow Control -if-integer expression

#!/bin/bash

if [ $# -ne 1 ]; thenecho "Usage: test-int value"exit 1

fi

int=$1

if [ $int -lt 0 ]; thenecho -e "Negative, \c"

elseecho -e "Positive, \c"

fi

if [ $(($int % 2)) -eq 0 ]; thenecho even

elseecho odd

fi

example:script usage: scriptname [value]the script first tests if one positional parameter has been passed. If not it display an error message and returns an exit status of 1.

If one value has been passed the script check:● the value sign;● if the value is even or odd

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 39 /68

Expressions can be combined by using logical operators. The operators syntax is slightly different based on the type of test used:

Operation test [[ ]] and (( ))---------------------------------------------------------

AND -a &&OR -o ||NOT ! !

Flow Control -if-logical operators

The && and || can also be used as control operators that can perform branching:

command1 && command2 → command1 is executed, then command2 is executed if, and only if, command1 is successful.example: mkdir cartella && cd cartella

command1 || command2 → command1 is executed, then command2 is executed if, and only if, command1 is n't successful.example: [-d cartella] || mkdir cartella

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 40 /68

Flow Control - Looping With while / untilwhile loop

The syntax of the while command is:

while commands; do

commands

done

while evaluates the exit status of a list of commands. As long as the exit status is zero, it performs the commands inside the loop

cont=1

while [ $cont -le 5 ]; doecho $countcont=$(($cont+1))

done

echo “Finished”

example: display five numbers in sequential order from one to five

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 41 /68

Flow Control - Looping With while / untiluntil loop

The syntax of the until command is:

until commands; do

commands

done

until evaluates the exit status of a list of commands. It performs the commands inside the loop until it receives a zero exit status

The until command is much like while, except instead of exiting a loop when a nonzero exit status is encountered, it does the opposite.

cont=1

until [ $cont -gt 5 ]; doecho $countcont=$(($cont+1))

done

echo “Finished”

example: display five numbers in sequential order from one to five

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 42 /68

bash provides two builtin commands that can be used to control program flow inside loops:

break → the break command immediately terminates a loop, and program control resumes with the next statement following the loop

continue → the continue command causes the remainder of the loop to be skipped, and program control resumes with the next iteration of the loop

Flow Control - Looping With while / untilbreaking out a loop

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 43 /68

The for loop differs from the while and until loops in that it provides a means ofprocessing sequences during a loop.

for variable [in words]; docommands

done

Traditional Shell Form:

for (( expression1; expression2; expression3 )); docommands

done

C Language Form:

Flow Control - Looping With forfor loop

The for loop is available in two forms

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 44 /68

the traditional shell form's syntax of the for loop is :

for variable [in words]; docommands

done

Where:● variable is the name of a variable that will increment during the execution of the loop;● words is an optional list of items that will be sequentially assigned to variable; ● commands are the commands that are to be executed on each iteration of the loop

Flow Control - Looping With forfor loop – traditional shell form

example: for is given a list of four words: “A”, “B”, “C”, and “D”:for var in A B C D; do

echo $var; done

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 45 /68

paolo@ubuntu-server:~/scripts$ for var in {A..D}; do echo $var; doneABCDpaolo@ubuntu-server:~/scripts$

The really powerful feature of for is the number of interesting ways we can create the list of words

#1: the list of words is given through brace expansion:

Flow Control - Looping With forfor loop – traditional shell form

paolo@ubuntu-server:~$ for i in $(ls); do echo $i ; donecompiledisk_spacescriptsscripts.tgzsourcepaolo@ubuntu-server:~$

#2: the list of words is given through command substitution:

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 46 /68

paolo@ubuntu-server:~/source$ for var in *; do echo $var; doneclient.cresolv-name.cserver.cpaolo@ubuntu-server:~/source$

#3: the list of words is given through pathname expansion:

Flow Control - Looping With forfor loop – traditional shell form

If the optional “in words” portion of the for command is omitted, for defaults to processing the positional parameters.

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 47 /68

Flow Control: Branching With case

case is the bash multiple-choice compound command. His general syntax is:

case word in[pattern [| pattern]...) commands ;;]...

esac

The case command looks at the value of word, the value of a variable, and then attempts to match it against one of the specified patterns. When a match is found, the commands associated with the specified pattern are executed. After a match is found, no further matches are attempted.

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 48 /68

Flow Control: Branching With casecase - patterns

The patterns used by case are the same as those used by pathname expansion. Patterns are terminated with a “)” character.

Here are some examples of valid patterns: Pattern Description---------------------------------------------------------------------------

a) ...................... Matches if word equals “a”.[[:alpha:]]) ................ Matches if word is a single alphabetic

character. ???) ..................... Matches if word is exactly three characters

long. *.txt) .................... Matches if word ends with the characters

“.txt”. *) ...................... Matches any value of word. It is good practice

to include this as the last pattern in a casecommand, to catch any values of word that didnot match a previous pattern; that is, to catchany possible invalid values.

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 49 /68

Here is an example of case usage:

#!/bin/bash#read -p "enter word > "

case $REPLY in

[[:alpha:]]) echo "is a single alphabetic character." ;;

[ABC][0-9]) echo "is A, B, or C followed by a digit." ;;

???) echo "is three characters long." ;;

*.txt) echo "is a word ending in '.txt'" ;;

*) echo "is something else." ;;esac

Flow Control: Branching With casecase examples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 50 /68

A typical application of case is to create a script menu like in the example below:

#!/bin/bashclear # case-menu: a menu driven system information programecho -e "Please Select:\nA. Display System InformationB. Display Logged on UsersC. Display Home Space UtilizationQ. Quit"read -p "Enter selection [A, B, C or Q] > "case $REPLY in q|Q) echo -e "\nProgram terminated.\n" ; exit ;; a|A) echo -e "\nHostname: $HOSTNAME" ; uptime ;; b|B) echo ; who ;; c|C) echo -e "\nHome Space Utilization ($USER)"; du -sh $HOME ;; *) echo -e "\nInvalid entry\n" >&2 exit 1 ;;esacecho

Flow Control: Branching With casecase examples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 51 /68

Shell Functions

shell functions are “mini-scripts” that are located inside other scripts

function name {commandsreturn

}

where, in both cases, name is the name of the function and commands is a series of commands contained within the function

Shell functions have two equivalent syntactic forms: name () {

commandsreturn

}

definition

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 52 /68

a script that demonstrates the use of a shell function

1 #!/bin/bash23 # Shell function demo45 function funct {6 echo "Step 2"7 return8 }910 # Main program starts here1112 echo "Step 1"13 funct14 echo "Step 3"

Shell Functionsexample

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 53 /68

#!/bin/bash

foo=0 # global variable foo

funct_1 () {local foo # variable foo local to funct_1foo=1echo "funct_1: foo = $foo"

}

funct_2 () {local foo # variable foo local to funct_2foo=2echo "funct_2: foo = $foo"

}

echo "global: foo = $foo"funct_1echo "global: foo = $foo"funct_2echo "global: foo = $foo"

[me@linuxbox ~]$ local-varsglobal: foo = 0funct_1: foo = 1global: foo = 0funct_2: foo = 2global: foo = 0

Global variables:They maintain their existence throughout the program.

Local variables:They are only accessible within the shell function in which they are defined and cease to exist once the shell function terminates

Shell Functionslocal and global variables

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 54 /68

Positional parameters can also be used to pass arguments to shell functions:

#!/bin/bash#function myfunc(){ echo "\$1 = $1" echo "\$2 = $2" echo "\$3 = $3" echo echo "\$@ = $@" # x=2 # Global variable # echo "myfunc : Global \$x = $x" # local x # Local variable x=3 # echo "myfunc : Local \$x = $x" echo}

...

...# Main script start here#x=1 # Global variable #echoecho "main: Global \$x = $x"#myfunc 1 2 3 4

echo "main: Global \$x = $x"echo#

Shell Functionsfunction with parameters

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 55 /68

the output produced from the previous' slide example is: main: Global $x = 1

$1 = 1$2 = 2$3 = 3

$@ = 1 2 3 4

myfunc : Global $x = 2myfunc : Local $x = 3

main: Global $x = 2

x form main script

Positional parameter inside the function

access at the global variable x inside the function

global variable x form main script

Shell Functionsfunction with parameters

access at the local variable x inside the function

summarizing

a shell function cannot change positional parameters;a shell function can change global variables (parameters);local variables can be declared in a shell function;

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 56 /68

A function may return a value in one of four different ways:

change the state of a global variable or variables;

use the exit command to end the shell script;

use the return command to end the function, and return the supplied value to the calling section of the shell script.

echo output to stdout, which will be caught by the caller just as c=`expr $a + $b` is caught;

Shell Functionsfunction returned value

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 57 /68

when writing a suite of scripts, it is often easier to write a "library" of useful functions, and source that file at the start of the other scripts which use the functions.Here there are two user shell scripts, function2.sh and function3.sh, each sourceing the common library file common.lib, and using variables and functions declared in that file:

#!/bin/bash# function2.sh. ./common.libecho $STD_MSGrename txt bak

#!/bin/bash# function3.sh. ./common.libecho $STD_MSGrename html html-bak

# common.lib, Note no #!/bin/shSTD_MSG="About to rename some files..."rename(){ # called as: rename .txt .bak FROM=$1 TO=$2 for i in *$FROM do j=`basename $i $FROM` mv $i ${j}$TO done}

Shell Functionsfunction and libraries

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 58 /68

Reading Keyboard Inputread values from standard input

The read builtin command is used to read a single line of standard input. This command can be used to read keyboard input or, when redirection is employed, a line of data from a file.

The command has the following syntax:

read [-options] [variable...]

where options is one or more of the available options listed later in these slides and variable is the name of one or more variables used to hold the input value.

If no variable name is supplied, the shell variable REPLY contains the line of data.

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 59 /68

#!/bin/bash#read multiple values from keyboardecho -n "Enter one value > "read varecho "var = $var"

paolo@ubuntu-server:~/source$ read-multipleEnter one or more values > a var = a

Reading Keyboard Inputexamples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 60 /68

#!/bin/bash#read multiple values from keyboardecho -n "Enter one or more values >"read var1 var2 var3 var4 var5echo "var1 = '$var1'"echo "var2 = '$var2'"echo "var3 = '$var3'"echo "var4 = '$var4'"echo "var5 = '$var5'"

paolo@ubuntu-server:~$ read-multipleEnter one or more values > a b c d evar1 = 'a'var2 = 'b'var3 = 'c'var4 = 'd'var5 = 'e'paolo@ubuntu-server:~$ read-multipleEnter one or more values > avar1 = 'a'var2 = ''var3 = ''var4 = ''var5 = ''paolo@ubuntu-server:~$ read-multipleEnter one or more values > a b c d e f gvar1 = 'a'var2 = 'b'var3 = 'c'var4 = 'd'var5 = 'e f g'

Reading Keyboard Inputexamples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 61 /68

#!/bin/bash# read-single: read multiple values into default variableecho -n "Enter one or more values > "readecho "REPLY = '$REPLY'"

If no variables are listed after the read command, a shell variable, REPLY, will be assigned all the input:

paolo@ubuntu-server:~/source$ read-singleEnter one or more values > a b c dREPLY = 'a b c d'

Reading Keyboard Inputexamples

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 62 /68

Option Description----------------------------------------------------------------------------a array .............Assign the input to array, starting with index zero.-d delimiter .........The first character in the string delimiter is used

to indicate end of input, rather than a newlinecharacter.

-e ...................Use Readline to handle input. This permits inputediting in the same manner as the command line.

-i string.............Use string as a default reply if the user simply presses Enter. Requires the -e option.

-n num ...............Read num characters of input, rather than an entireline.

-p prompt ............Display a prompt for input using the string prompt.-r ...................Raw mode. Do not interpret backslash characters as

escapes.-s ...................Silent mode. Do not echo characters to the display as

they are typed. This is useful when inputtingpasswords and other confidential information.

-t seconds ...........Timeout. Terminate input after seconds. read returns anon-zero exit status if an input times out.

-u fd ................Use input from file descriptor fd, rather thanstandard input.

Reading Keyboard Inputread options

Paolo Santinelli AS 2014/2015Sistemi e Reti

ITIS E. Fermi, Modena 63 /68

- Bash exercises -entry level

1. Write a bash script called greeting that prints a greeting to the logged user -- perhaps "Good morning [username]” or something similar.

2. Now modify your script greeting so that it:

prints the current date;prints a list of users currently logged onto the computer.

Good morning, mcoahran.Date is Sun Apr 20 12:22:47 CDT 2008Users on Leah:mcoahran :0 2008-04-20 11:45mcoahran pts/0 2008-04-20 11:45 (:0.0)mcoahran pts/1 2008-04-20 11:49 (:0.0)

Paolo Santinelli AS 2014/2015Sistemi e Reti

ITIS E. Fermi, Modena 64 /68

3. Modify your script greeting to present a different greeting based on the time of day. For example, your greeting could be "good morning", "good afternoon", "good evening", or "YOU SHOULD BE SLEEPING!" based on the current hour. Note that the following command can be used to return the (24-hour) hour of the current time: date +%k.

4. Write a script called countdown that prints output similar to the following:10987654321GO!

- Bash exercises -entry level

Paolo Santinelli AS 2014/2015Sistemi e Reti

ITIS E. Fermi, Modena 65 /68

5.Write a script called countdown2 that accepts the initial value as a command-line argument. For example, the command and its output might look like the following:

$ ./countdown2 887654321GO

7. Modify the script countdown2 to check for correct usage. The script should print a usage message and exit if it does not receive exactly one argument. An example session might look like this:

$ ./countdown2 Usage: countdown2 initial-value

- Bash exercises -entry level

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 66 /68

Write a script called addnames that is to be called as follows, where classlist is the name of the classlist file, and username is a particular student's username.

./addnames classlist username

The script should:check that the correct number of arguments was received and print an usage message if not;check whether the classlist file exists and print an error message if not;check whether the username is already in the file, and then either:

print a message stating that the name already existed, oradd the name to the end of the list.

Hint: Use a for-loop to process each line in the file. To create a list of lines in the file, remember that you can use any bash construct inside a script that you can use in the terminal window. How would you list the lines of the file in the terminal window? Similarly, how would you append a particular item to the end of an existing file from the terminal window?

- Bash exercises -useful scripts

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 67 /68

Write a script called submit-dirs that is to be called as follows.

./submit-dirs classlist

The script should:

check whether the correct number of arguments was received and print a usage message if not;check whether the classlist file exists and print an error message if not;create a directory named submit within the current directory (but only if one does not already exist);create a directory within the directory submit for each student in the class (but only if one does not already exist). These student directories should be named according to the students' usernames.

- Bash exercises -useful scripts

Paolo Santinelli / Lorena Marassi AS 2015/2016Sistemi e Reti

ITIS E. Fermi, Modena 68 /68

The purpose of the script is to check network connectivity ./netck

The script should:

check for network connectivity sending two ICMP/IP packets to the target site google.com using ping;store the target site in a variable;send to the standard outputs suitable messages related with the test results. The messages have to include the date of the day;return the exit value 0 in case of test success and any other value in case of failure ;

- Bash exercises -useful scripts