Notes on shell scripting.
Bash is a Unix shell and command language originally released in 1989. It can read and execute text files called shell script that are useful for automating tasks.
The terminal cheatsheet contains some of the commands that can be run as part of a bash script.
Running a script
Navigate to the directory containing the script and use ./scriptname.sh
to execute it.
If the script fails with an permissions error, use chmod +x scriptname.sh
to make it executable.
#! | Shebang. Indicates which interpreter a script should be run with: #!/bin/bash |
$1, $2, ... | The first, second, etc command line arguments to the script. |
variable=value | To set a value for a variable. Remember, no spaces on either side of the equal sign |
Conditional logic
# conditional logic if [ -d $HOME ]; then echo "The home directory path is $HOME" else echo "Couldn't find home directory!" fi # use semi colon when writing one liners if [ -f $file ]; then echo "Found $file"; fi # use double brackets to combine conditions if [[ $condition == true && ! -n $value ]]; then echo "The $condition is true and value was not set." fi # comparisons if [[ $value -gt 0 && $value -lt 100 ]]; then echo "$value is greater than 0 and less than 100" fi
Strings
# print variable to text file overwriting existing content echo $string > $file # append a string to a text file echo $string >> $file # store file content as variable string=$(cat $file) # read from stdin read -p "> " $string echo "You entered $string" # print the length of a string ${#string} # replace substring string="The wind came from North East" string=${string/"East"/"West"} # "The wind came from North West" # various string manipulations path="directory/file.txt" file=$(basename $path) # file.txt fileName="${file%%.*}" # file fileExt="${fileName#*.}" # ext string="VWXYZ" new="${string:2}" # "XYZ" new="${var%???}" # "VW" string="Location: Earth" new="${string%%:*}" # "Location" # find substring if [[ $string == "$subString"* ]]; then echo "$subString was found at the beginning of $string" elif [[ $string == *"$subString"* ]]; then echo "$subString was found in the middle of $string" elif [[ $string == *"$subString" ]]; then echo "$subString was found at the end of $string" else echo "$subString was not found in $string" fi # string formatting bold=$(tput bold) normal=$(tput sgr0) echo "${bold}This text is bold.${normal}"
Arrays
#!/bin/bash # define an array array=( "item1" "item2" "item3" ) # add an item to an array array+=('item4') # get the size of an array echo ${#array[@]} # loop through array items for item in ${array[@]}; do echo $item done # read words from file and store them in an array file="words.txt" words=() count=0 # read from file while read line; do words[$count]="$line" let count++ done < $file # read from array for line in "${words[@]}"; do echo ${line} done
Loops
# reads a text file line by line while read line; do echo $line done < $file # count files in folder count=0 for $file in $path/*; do echo $file let count++ done # print files of type txt for $file in $path/*.txt; do echo $file done
Snippets
# use bash parameter expansion to set default variable values FOO="${VARIABLE:-default}" # start a program as a forked process in a new window programname & # erases the last line printed in the terminal tput cuu1;tput el; # stopping time for script execution duration startBuild=$(date +%s,%N) _s1=$(echo $startBuild | cut -d',' -f1) # sec _s2=$(echo $startBuild | cut -d',' -f2) # nano sec # run commands end_at=$(date +%s,%N) _e1=$(echo $end_at | cut -d',' -f1) _e2=$(echo $end_at | cut -d',' -f2) # calculate passed time in seconds passedTime=$(bc <<< "scale=3; $_e1 - $_s1 + ($_e2 -$_s2)/1000000000") echo "The process took $passedTime seconds." # output the name of all screen devices function getScreenDevices() { # Uses xrandr to find all connected devices and stores their names in an array scrns=$(xrandr | grep -o '.* connected ') # scrns=$(grep -o ".* connected " test.txt) while IFS= read -r screen; do screen=${screen%% c*} SCREENS+=("$screen") done <<< "$scrns" for screen in ${SCREENS[@]}; do echo $screen done }
Debugging
Use set
with the following parameters for easier debugging:
e | Halts on the first error. |
u | Halts on unset variables. |
o -pipefail | Halts on errors |
v | Prints each line before it is executed. |
x install |
Prints each line after all substitutions and expansions have been performed. |
Evaluating the arguments passed to a script
#!/bin/bash # case example case $1 in start) echo starting ;; stop) echo stoping ;; restart) echo restarting ;; *) echo don\'t know ;; esac
Links
incoming(12) | relogen | logbook | memoir | scim | meta | trabant | cintiq | printer | camera | photography | terminal | rsync