Introduction to Shell Scripting
Bash system
-
Navigate to a terminal to with a bash shell
-
Make a new directory with the
mkdircommand calledShell, and the change to that directory$ cd ~/path/to/Shell -
Make new directory,
$ mkdir scriptingand again change directory toscripting
Task 1. #! Shebang/hashbang
-
Create a new file called
script.sh -
Then edit the file
-
remember
^is the ctrl key andMis the alt key. You use the control keys in combination with a letter or symbol to use nano:- for instance:
- to save the current file you can use Write Out ctrl + O (
Oas in Oscar.) - to exit the file ctrl + X, if there is a change in the file you will be prompted to save.
- to undo the use the alt + U
- to save the current file you can use Write Out ctrl + O (
- for instance:
-
-
Reproduce the following...
-
Write out ctrl + X
-
Modify the file's mode bits so that it becomes an executable
-
performing
ls -leither side of thechmodcommand shows the information about the file such as its mode bits.-
Before:
-
After:
-
-
-
Now you are going to run the script two ways.
-
first way is to call the script via bash directly:
-
Ouput:
-
-
Second way is to run the script as an executable
-
Ouput:
-
-
Lets modifiy the script so that the
#! /usr/bin/env wc-
write out
ctrl+x -
What will running the script do?
-
Run it and find out.
-
Task 2. Variables
-
create a new file and call it
int-or-string.sh -
Reproduce the following inside that
int-or_string.h:#! /usr/bin/env bash A=2334 # Integer... though still a string echo "A = ${A} " # a = 2335 A=$(( ${A} + 1 )) # increment A by 1. echo "A = ${A} " # a = 2335, Integer, still. echo # new empty lineRemeber to save it ctrl + O (O for Oscar), and exit ctrl + X
-
You can change the mode bits again if you like or run with just
bash.-
Output:
-
This behaved as expected, using arthemtric expansion
$((...))to increment variableAby 1.
-
-
Using
nanomodifyint-or-string.shto include, pay attention to the comments.B=${A/23/BB} # Substitute "23" stored in variable "A" for "BB". # This transforms $b into a string. echo "B = ${B}" # B = BB35 declare -i B # Declaring it an integer doesn't help. echo "B = ${B}" # B = BB35 B=$(( ${B} + 1 )) # BB35 + 1 echo "B = $B" # B = 1 echo # Bash sets the "integer value" of a string to 0. C=BB34 echo "C = $C" # C = BB34 D=${C/BB/23} # Substitute "23" for "BB". # This makes $D an integer. echo "D = ${D}" # D = 2334 D=$(( ${D} + 1 )) # 2334 + 1 echo "D = ${D}" # D = 2335 echo-
Output:
-
-
Still on Variables... create a new script called
my-name-is.sh-
reproduce the following code, like from the lecture slide.
-
again note the Uppercase standard for naming convention here.
-
Notice how not all variables values are explicitly declared as string
"". You only need to do this if there are spaces between letters/words. -
run the command.
-
Output:
- But hold on... what about
NAME=${1:-"Slim Shady"}- Well this special operation allows default values to be assigned to the variable if something is
nullsuch as1is the positional number for a parameter coming into the script when it is called from the command line interface (CLI) if this isnullthen setNAME=Slim Shady.
- Well this special operation allows default values to be assigned to the variable if something is
- But hold on... what about
-
Try calling the script but this time provide your first name, or mulitple names encapsulated with
"name name name" -
Output:
-
Task 3. Loops
-
Create a new script called
forloops.sh -
Reproduce the following code, pay attention to the comments.
#! /usr/bin/env bash DIR="task5" # if directory (-d) does not exist (!), then create it if [[ ! -d ${DIR} ]]; then mkdir ${DIR} && echo "${DIR} created" # if successful printout created fi # a becomes 1 then 2, and 3 and this is appended to the word foo_ to # create files in the directory that was created. for a in 1 2 3 ; do touch ${DIR}/foo_$a done -
Run this command, and see if you get a new directory filled with files.
-
You can check by running the
ls | wc -lcommand in terminal: -
Lets modify
forloops.shusingnano:#! /usr/bin/env bash DIR="task5" # if directory (-d) does not exist (!), then create it if [[ ! -d ${DIR} ]]; then mkdir ${DIR} && echo "${DIR} created" # if successful printout created fi # counts the number of files in the directory # you can run commands and save the outputs to variables using $(...) COUNT=$( ls ${DIR} | wc -l ) # arthimetic operations can be formed using $((...)) BOUND=$(( ${COUNT}+5 )) # using the seq command you can create sequence from one number to # another... seq a b, 1 to 10 for example. # this way we can create a new file proceeding the last file in the dir for a in $( seq ${COUNT} ${BOUND} ) ; do touch ${DIR}/foo_$a done -
Run the command and perform the command
ls task5/ | wc -lto see if the files have been created. Rinse and repeat a few times to see if it works. -
Now create a
whileloop.shfile
- Run this and see the output in the terminal,
- experiment with:
-ltless than-leless than equal to-eqequal to-gegreater than equal to-gtgreater than
- experiment with:
Task 4. Special parameters and conditions
So now you are going to understand in more detail how parameters work.
-
Create a new script called
parameters.sh -
edit the script to look like this:
#! /usr/bin/env bash while getopts u:a:f: flag do case "${flag}" in u) username=${OPTARG};; a) age=${OPTARG};; f) fullname=${OPTARG};; esac done echo "Username: $username" echo "Age: $age" echo "Full Name: $fullname"-
Run the script by only supplying your username, age and full name.
-
What happened?
-
Try again this time provide your a
-uthen the username. -
Repeat but provide all options
-u,-a, and-f
-
-
Modify the code again, so that parameters can be precheck before coming to
getopts#! /usr/bin/env bash if [[ $# -gt 6 ]];then echo -e "Too many arguments supplied:\n$#" exit 1 elif [[ $# == 0 ]]; then echo -e "Not enough arguments supplied:\n$#" exit 1 fi while getopts u:a:f: flag do case "${flag}" in u) username=${OPTARG};; a) age=${OPTARG};; f) fullname=${OPTARG};; esac done echo "Username: $username" "Age: $age" "Full Name: $fullname"
-
Try to run the script with no parameters, what happens?
-
Try to run the script with more than 6 parameters, what happens?
-
What about providing a flag that is not accounted for?
Task 5. Reading from stdin
Here you are replicating what was in the lecture using the read command to caputer user input.
-
create a new script called
userinput.sh -
reproduce the following code, pay attention to the comments:
#! /usr/bin/env bash echo -n "Enter your name:" read NAME # stores user's input echo "Your name is:" ${NAME} # prints user's input # prompt with and stores user's input read -p "Enter your name: " NAME echo Your name is ${NAME}. # prompt with suppressed feature enable so user input is hidden read -t 5 -p "Enter your password: "$'\n' -s PASSWORD echo ${PASSWORD} # though it is stored as plain text here... read -a WORDS <<< "Hello world!" # stores an array '-a` echo ${WORDS[0]} # accessing the arrays indicies echo ${WORDS[1]} echo ${WORDS[@]} # access the entire array echo ${#WORDS[1]} # get length of the index echo ${#WORDS[@]} # get lenght of array -
Run the code, what output/experience do you get?