Scripting is useful to perform complex interaction with programs and data. We revise basic commands to write simple bash scripts.
Values can be assigned to variables using
= symbol and can be referred to by prepending a
$ var1=goofy $ var2=pluto $ echo $var2 is $var1\'s dog pluto is goofy's dog
= symbol needs to be near variable name and value, adding spaces would give an error as var1 would be considered a command to execute:
$ var1 = goofy var1: command not found
Inside double quotes variables are still replaced with their value. Notice that with double quotes it is not necessary to escape the single quote:
$ var1=goofy $ var2=pluto $ echo "$var2 is $var1's dog" pluto is goofy's dog
Single quotes, instead, prevent variable replacement, as shown below. Notice that we need to close the quote, escape the ‘ character we want to print and reopen the single quote:
$ var1=goofy $ var2=pluto $ echo '$var2 is $var1'\''s dog' $var2 is $var1's dog
Finally, it is possible to concatenate commands using
; and to break into different lines by ending each line with
\. For example:
$ var1=goofy; var2=pluto; echo "$var2 is $var1's dog" pluto is goofy's dog $ var1=goofy;\ > var2=pluto;\ > echo "$var2 is $var1's dog" pluto is goofy's dog
Executable script files
Writing long sequences of commands on the command-line might become complicate. It is possible to write scripts in files and execute them, as we would do with programs. It is important to remember, however, that shell scripts are interpreted by the shell as if they were entered from the command line. There is no compiler or static analysis of the code.
When we write a shell script we need to start with a directive telling the system what interpreter will be used. For example, using bash, we will write:
#!/bin/bash var1=goofy var2=pluto echo "$var2 is $var1's dog"
We can save this in a file named
script1.sh, make it executable with
chmod u+x script1.sh and execute it:
$ ./script1.sh pluto is goofy's dog
Write a script that generates and execute another script that, in turns, prints Hello World.
Parameters passed on the command line can be accessed by scripts through special variables:
$0, $1, … , $nrefer to parameters 0, 1, … , n;
$#contains the number of parameters;
$@contains the list of all parameters, separated by a blank space.
#!/bin/bash echo "Number of parameters: $#" echo "List of parameters: $@"
gives the following output:
$ ./script-parameters.sh 1 2 3 test hello world Number of parameters: 6 List of parameters: 1 2 3 test hello world
Iterating over list elements (for loop)
In order to process parameters (or in general elements of a list) one by one, we can use a for loop as follows:
#!/bin/bash for par in $@ do echo $par done
which behaves as follows:
$ ./script-for-loop.sh 1 2 3 test hello world 1 2 3 test hello world
We give a simple example of if-then-else constructs:
#!/bin/bash if [ "$#" -ne 2 ] then echo "[ERROR] Two parameters expected" exit fi if [ "$1" -eq "$2" ] then echo "$1 = $2" elif [ "$1" -gt "$2" ] then echo "$1 > $2" elif [ "$1" -lt "$2" ] then echo "$1 < $2" else echo "[ERROR] Something went wrong, you should insert numbers" fi
Here is what we get when we execute the script:
$ ./script-if.sh [ERROR] Two parameters expected $ ./script-if.sh 1 2 3 [ERROR] Two parameters expected $ ./script-if.sh 1 2 1 < 2 $ ./script-if.sh 2 2 2 = 2 $ ./script-if.sh 3 2 3 > 2 $ ./script-if.sh 3 hello ./script-if.sh: line 7: [: hello: integer expression expected ./script-if.sh: line 10: [: hello: integer expression expected ./script-if.sh: line 13: [: hello: integer expression expected [ERROR] Something went wrong, you should insert numbers
Notice that numeric comparisons cannot be performed using
> since the shell treats them as redirection operators. To see the full list of expressions supported type
man [ or, equivalently,
It is often very useful to execute a command and assign its output to a variable. This can be done using syntax
$( command ). An example follows:
$ ls file1.txt mysite.html script.sh $ myls="$( ls )" $ echo "$myls" file1.txt mysite.html script.sh
Write a script that renames any .html file into uppercase .HTM ones. For example website.html should become WEBSITE.HTM. Renaming can be done via
mv command while name conversion has been treated in Exercise 2 of previous class.