18/08/19
Shell scripts
• script: A short program meant to perform a targeted task.
a series of commands combined into one executable file
Lecture 5 • shell script: A script that is executed by a command-line shell.
bash (like most shells) has syntax for writing script programs
if your script becomes > ~100-150 lines, switch to a real language
Intro to shell scripting • To write a bash script (in brief):
type one or more commands into a file; save it
type a special header in the file to identify it as a script (next slide)
enable execute permission on the file
run it!
1 2
1 2
Basic script syntax Running a shell script
#!interpreter • by making it executable (most common; recommended):
written as the first line of an executable script; causes a file to be chmod u+x myscript.sh
treated as a script to be run by the given interpreter ./myscript.sh
• (we will use /bin/bash as our interpreter) fork a process and run commands in myscript.sh and exit
• Example: A script that removes some files and then lists all files: • by launching a new shell :
bash myscript.sh
#!/bin/bash
advantage: can run without execute permission (still need read
rm output*.txt permission)
ls -l
• by running it within the current shell:
source myscript.sh
advantage: any variables defined by the script remain in this shell
(more on variables later)
3 4
3 4
1
18/08/19
echo Script example
command description #!/bin/bash
clear # please do not use clear in your hw scripts!
echo produces its parameter(s) as output echo "Today's date is $(date)"
(the println of shell scripting) echo
-n flag to remove newline (print vs println)
echo "These users are currently connected:"
w -h | sort
• Example: A script that prints your current directory.
echo
#!/bin/bash
echo "This is my amazing script!" echo "This is $(uname –s) on a $(uname –m) processor."
echo
echo "Your current dir is: $(pwd)"
echo "This is the uptime information:"
• Exercise : Write a script that when run on attu does the following: uptime
clears the screen echo
echo "That's all folks!"
displays the current date/time
Shows who is currently logged on & info about processor
5 6
5 6
Comments Shell variables
# comment text • name=value (declaration)
bash has only single-line comments; there is no /* ... */ equivalent must be written EXACTLY as shown; no spaces allowed
often given all-uppercase names by convention
• Example: once set, the variable is in scope until unset (within the current shell)
#!/bin/bash
AGE=64
# Leonard's first script ever
NAME="Michael Young"
# by Leonard Linux
echo "This is my amazing script!"
echo "The time is: $(date)" • $name (usage)
echo "$NAME is $AGE years old"
# This is the part where I print my current directory
echo “Current dir is: $(pwd)" Produces:
Michael Young is 64 years old
7 8
7 8
2
18/08/19
Common errors More Errors…
• if you misspell a variable's name, a new variable is created • Using $ during assignment or reassignment
NAME=Ruth $mystring=“Hi there” # error
...
Name=Rob # oops; meant to change NAME mystring2=“Hello”
…
• if you use an undeclared variable, an empty value is used $mystring2=“Goodbye” # error
echo "Welcome, $name" # Welcome,
• Forgetting echo to display a variable
$name
• when storing a multi-word string, must use quotes
echo $name
NAME=Ruth Anderson # Won’t work
NAME=“Ruth Anderson" # $NAME is Ruth Anderson
9 10
9 10
Capture command output Double vs. Single quotes
Double quotes - Variable names are expanded & $() work
variable=$(command)
NAME="Bugs Bunny"
captures the output of command into the given variable echo "Hi $NAME! Today is $(date)"
Produces:
Hi Bugs Bunny! Today is Tues Apr 25 13:37:45 PDT 2017
• Simple Example:
FILE=$(ls *.txt) Single quotes – don’t expand variables or execute commands in $()
echo $FILE echo 'Hi $NAME! Today is $(date)'
Produces:
• More Complex Example: Hi $NAME! Today is $(date)
FILE=$(ls -1 *.txt | sort | tail –n 1) Tricky Example:
echo "Your last text file is: $FILE" STAR=* Lesson: When referencing a variable, it is
good practice to put it in double quotes.
• echo "You are a $STAR"
What if we use double quotes instead? • echo 'You are a $STAR'
• echo You are a $STAR
11 12
11 12
3
18/08/19
Types and integers Bash vs. Java
• most variables are stored as strings Java Bash
operations on variables are done as string operations, not numeric String s = "hello"; s=hello
System.out.println("s"); echo s
System.out.println(s); echo $s
• to instead perform integer operations:
s = s + "s"; // "hellos" s=${s}s
x=42 String s2 = "25"; s2=25
y=15 String s3 = "42"; s3=42
let z="$x + $y" # 57 String s4 = s2 + s3; // "2542" s4=$s2$s3
int n = Integer.parseInt(s2) let n="$s2 + $s3"
+ Integer.parseInt(s3); // 67
• integer operators: + - * / %
bc command can do more complex expressions x=3
x vs. $x vs. "$x" vs. '$x' vs. \'$x\' vs. 'x'
• if a non-numeric variable is used in numeric context, you'll get 0
13 14
13 14
Special variables $PATH
variable description • When you run a command, the shell looks for that program in all
$DISPLAY where to display graphical X-windows output the directories defined in $PATH
$HOSTNAME name of computer you are using • Useful to add commonly used programs to the $PATH
$HOME your home directory
$PATH list of directories holding commands to execute • Exercise: modify the $PATH so that we can directly run our shell
$PS1 the shell's command prompt string script from anywhere
$PWD your current directory echo $PATH
$SHELL full path to your shell program PATH=$PATH:/homes/iws/rea
$USER your user name
these are automatically defined for you in every bash session • What happens if we clear the $PATH variable?
• Exercise : Change your attu prompt to look like this:
jimmy@mylaptop:$
See man bash for more info (search on PROMPTING)
15 16
15 16
4
18/08/19
set, unset, and export Console I/O
shell command description shell command description
set sets the value of a variable read reads value from console and stores it into a variable
(not usually needed; can just use x=3 syntax) echo prints output to console
unset deletes a variable and its value printf prints complex formatted output to console
export sets a variable and makes it visible to any
programs launched by this shell variables read from console are stored as strings
readonly sets a variable to be read-only
(so that programs launched by this shell cannot • Example:
change its value)
#!/bin/bash
typing set or export with no parameters lists all variables read -p "What is your name? " name
Exercise: set a local variable, and launch a new bash shell read -p "How old are you? " age
• Can the new shell see the variable? printf "%10s is %4s years old" $name $age
• Now go back and export and launch a shell again. Can you see it now?
17 18
17 18
Command-line arguments for loops
for name in value1 value2 ... valueN; do
variable description
commands
$0 name of this script
done
$1, $2, $3, ... command-line arguments
$# number of arguments
• Note the semi-colon after the values!
$@ array of all arguments • the pattern after in can be:
a hard-coded set of values you write in the script
Example.sh: a set of file names produced as output from some command
command line arguments: $@
#!/bin/bash
echo “Name of script is $0” • Exercise: create a script that loops over every .txt file in the
echo “Command line argument 1 is $1” directory, renaming the file to .txt2
echo “there are $# command line arguments: $@”
for file in *.txt; do
mv $file ${file}2
• Example.sh argument1 argument2 argument3
done
19 20
19 20
5
18/08/19
for loop examples Exercise
for val in red blue green; do • Write a script createhw.sh that creates directories named hw1,
echo "val is: $val" hw2, ... up to a maximum passed as a command-line argument.
done
$ ./createhw.sh 8
for val in $@; do
echo "val is: $val" Copy criteria.txt into each assignment i as criteria(2*i).txt
done Copy script.sh into each, and run it.
• output: Script running on hw3 with criteria6.txt ...
for val in $(seq 4); do
echo "val is: $val"
done
command description
seq outputs a sequence of numbers
21 22
21 22
Exercise solution
#!/bin/bash
# Creates directories for a given number of assignments.
for num in $(seq $1); do
let CRITNUM="2 * $num"
mkdir "hw$num"
cp script.sh "hw$num/"
cp criteria.txt "hw$num/criteria$CRITNUM.txt"
echo "Created hw$num."
cd "hw$num/"
bash ./script.sh
cd ..
done
23
23