5. Bash scripting¶
A bash script is a file containing commands that can run on the bash shell. They usually have the .sh extension.
A minimal example¶
Create a file named myscript.sh and insert the code from the example below.
#!/usr/bin/env bash
# A simple bash script
echo "Hello World"
Note
#! is called the “shebang”. It indicates the path to the program/interpreter that should be used to execute the script.
Execution¶
The permissions on the script you created should be set so you can execute it with either ./myscript.sh or bash myscript.sh. Sometimes the file might not have appropriate permissions set. For example:
$ ./myscript.sh
bash: ./myscript.sh: Permission denied
$ ls -l myscript.sh
-rw-r--r-- 18 dkishore users 4096 Jun 10 09:12 myscript.sh
To run this file, the permissions on the script need to be changed to allow for execution: chmod +x myscript.sh
Variables¶
#!/bin/bash
cp $1 $2
# Verification
echo Details for $2
ls -lh $2
$1 and $2 are the first and second arguments to the script.
Let’s experiment here. First, create a file named variables_test.sh and copy-paste the code above there. Next, try calling this file with myscript.sh as the first argument, and myscript2.sh as the second argument. What happened?
Note
$0refers to the name of the bash script
$#refers to the number of arguments passed to the script
$@refers to all the arguments supplied
$?refers to the exit status of the most recent process
You can also set your own variables inside the script:
#!/bin/bash
myvariable=Hello
anothervar=Fred
echo $myvariable $anothervar
sampledir=/etc
echo $sampledir
Note
Use quotes if your value has a space. For example:
myvar="Hello World!"When referring to or reading a variable we place a
$sign before the variable nameWhen setting a variable we leave out the
$signDo not use white-space around the
=
Input¶
Run the command read and save the users response into the variable varname as shown below. Then create a new shell script with the code below and run it. This is how you can have an interactive program.
#!/bin/bash
# Ask the user for their name
echo Hello, who am I talking to?
read varname
echo It\'s nice to meet you $varname
Conditional statements¶
Play with the scripts below. Do you understand what they are doing? If you don’t understand, make sure to test them out and ask us questions!
ifstatements
#!/bin/bash
# Basic if statement
if [ $1 -gt 100 ]
then
echo "Hey that\'s a large number."
pwd
fi
The square brackets in the if statement is a reference to the
testcommand.-gtis equivalent to >=. Similarly there are=,!=and many more.0 means TRUE and 1 means FALSE (fail).
if-else-if
#!/bin/bash
# elif statements
if [ $1 -ge 18 ]
then
echo "You may go to the party."
elif [ $2 == 'yes' ]
then
echo "You may go to the party but be back before midnight."
else
echo "You may not go to the party."
fi
Loops¶
whileloop
#!/bin/bash
# Basic while loop
counter=1
while [ $counter -le 10 ]
do
echo $counter
((counter++))
done
echo "All done"
untilloop (opposite of thewhileloop)
#!/bin/bash
# Basic until loop
counter=1
until [ $counter -gt 10 ]
do
echo $counter
((counter++))
done
echo "All done"
forloops
#!/bin/bash
# Basic for loop
names='Stan Kyle Cartman Kenny' # is one way to define lists
for name in $names
do
echo $name
done
echo All done
Ranges and iterators
#!/bin/bash
# Basic range in for loop
for value in {1..5}
do
echo $value
done
echo All done
Note
You can have custom range by providing a step. For example: {10..0..2}
Functions¶
Minimal example
#!/bin/bash
# Basic function
print_something () {
echo Hello I am a function
}
print_something
Passing arguments
#!/bin/bash
# Passing arguments to a function
print_something () {
echo Hello $1
}
print_something Mars
print_something Jupiter
Returning values
Bash functions don’t allow for return values, but they do allow for a return status.
#!/bin/bash
# Setting a return status for a function
print_something () {
echo Hello $1
return 5
}
print_something Mars
print_something Jupiter
echo The previous function has a return value of $?
Variable scope
#!/bin/bash
# Experimenting with variable scope
var_change () {
local var1='local 1'
echo Inside function: var1 is $var1 : var2 is $var2
var1='changed again'
var2='2 changed again'
}
var1='global 1'
var2='global 2'
echo Before function call: var1 is $var1 : var2 is $var2
var_change
echo After function call: var1 is $var1 : var2 is $var2
Results¶
Before function call: var1 is global 1 : var2 is global 2
Inside function: var1 is local 1 : var2 is global 2
After function call: var1 is global 1 : var2 is 2 changed again