Bash Scripting Note

Posted on: August 20, 2023

Create script file

  • touch <filename>.sh

Run script

  • Using sh - shell interpreter: sh <filename>.sh
  • Using bash - bourne-again shell interpreter: bash <filename>.sh
  • If interpreter is already defined in file: <path_to_file>

Find bash location

  • which bash

Tell program to use bash in file

  • Place a shebang at the very top of the file: #!<path_to_bash>
file="questionnaire.sh"
#!/bin/bash

Subshell

  • The code inside the parenthesis $(<code>) will run in a subshell, aka a separate bash process.
// Create a command variable to run a single psql command and exit
PSQL="psql -X --username=freecodecamp --dbname=students --no-align --tuples-only -c"
// Then use the format: `$($PSQL "<query_here>")`, and make sure the variable inside "" is single quoted if the type is varchar
MAJOR_ID=$($PSQL "SELECT major_id FROM majors WHERE major='$MAJOR'")

Permissions

Permissions types

  • r - read
  • w - write
  • x - execute

Actions

  • To see details/permissions: ls -l
  • To give permission to everyone: chmod +<permission> <filename>

Variables

Create variable

  • <VARIABLE_NAME>=<VALUE>, no space in between; put "" around a variable if has any spaces

Use variable

  • $<VARIABLE_NAME>
echo $NAME

Get and store user input as a variable

  • read <VARIABLE_NAME>

View variable

  • View all variables in the shell: declare -p. declare can be used to create or view variables. -p stands for print.
  • View one of the variables: declare -p <variable_name>
declare -p RANDOM
OR
$J=10
declare -p J // prints 10

Check undefined

  • -z means undefined or empty
if [[ -z $VAR ]]

Environment Variable

  • Predefined and loaded with each shell, can be viewed: printenv
  • RANDOM is an environment variable that generate a random number between 0 - 32767.
  • IFS - Internal Field Seperator, used to determine word boundaries, defaults to spaces, tabs and new lines. Works as split("") in js.
cat courses.csv | while IFS="," read MAJOR COURSE
do
echo $MAJOR
done
// So it prints the word before "," and $COURSE is the word after ","

Array

  • Create array: <arra_name>=(<var1> <var2> <var3>)
  • Access element: ${<arra_name>[<n>]}
  • Access all elements: ${<arra_name>[*]} or ${<arra_name>[@]}

Function

  • Create function:
FUNCTION_NAME() {
STATEMENTS
}
  • Access function by directly call function name: <function_name> without brackets
  • Pass argument: <function_name> <arg> without brackets

Arguments

Access arguements

  • Use $
  • All arguments: $*
// In script
echo $*
// In terminal pass in arguments
./countdown.sh arg1 arg2 arg3
// Terminal prints: arg1 arg2 arg3
  • Any one of them: $<number>
// In script
echo $1
// In terminal pass in arguments
./countdown.sh arg1 arg2 arg3
// Terminal prints the first argument: arg1

Comments and Shebang

Shebang

  • #!<path_to_interpreter>
  • Must be the first line in the script

Comment

  • One line comment: # <comment>, but a shebang is not a comment
  • Multi-line comment syntax:
: '
comment here
more comment here
'

If statements

  • If statement syntax:
if [[ CONDITION ]]
then
STATEMENTS
fi
  • If-else statement syntax:
if [[ CONDITION ]]
then
STATEMENTS
elif [[ CONDITION ]]
then
STATEMENTS
else
STATEMENTS
fi

While loop

  • Syntax: while COMMANDS; do COMMANDS; done
  • Loop through and print content in a file syntax:
cat <filename> | while read <var1> <var2>
do
STATEMENTS
done

Expresssion command

Syntax: [[ expression ]]

Get expression help menu

  • help [[ expression ]] or help [[

Arithmetic operation

  • Gets operators that can use with double parenthesis: help let

(( ... ))

  • Perform calculation or arithmetic operation, and output nothing
i=5
((i--)) // returns nothing
echo $i // prints 4
echo ((i--)) // returns syntax error

$(( ... ))

  • Replaces the cauclation wit the result of it, i.e. can be assign to a variable
i=5
$((i+2)) // returns `command not found`
echo $((i+2)) // prints 7
echo $i // prints 5 because it's not $((i+=2)) so i is not changed
j=$((i+2))
echo $j // prints 7
echo $i // still prints 5
j=$i+2
echo $j // prints 5+2 because bash sees everything as a string

Comparisons

Comparison expression

  • Use [[ ... ]]
[[ $NUMBER -le 30]]
  • Use (())
(( NUMBER <= 30 ))

Comparison symbol

  • -eq - equal
  • -ne - not equal
  • -lt - less than
  • -le - less than or equal
  • -gt - greater than
  • -ge - greater than or equal

Expression equals

  • == - equal
  • != - not equal
  • =~ - match a pattern
[[ "hello world" =~ "el wor"]]; echo $?
// returns 0 meaning true
or
// Using regex, regex don't need ""
[[ "hello world" =~ ^h ]]; echo $?
// returns 0

Help menu

  • More operators for comparisons and file type checks: help test

Exit status

Get exit status

  • Each command has an exit status that can be accessed with $?
[[ 4 -le 5]]
echo $? // Get the exit status of last command
// One line commands:
[[ 4 -ge 5]]; echo $?

Exit status of 0

  • Meaning true, also means the command had zero errors
[[ 4 -ge 5]]; echo $?
// Returns 0
  • Anthing but 0 means there was an error with the command.

Exit status of 1

  • Meaning false

Exit status of 127

  • Meaning "command not found"

Exit status of 2

  • Meaning "command was unsuccessful"

Non built-in commands

  • help can only find built-in commnads, non built-in can be found using ls \bin, where bin folder stands for binary

sleep command

  • To pause execute for n seconds: sleep <n>

Type

View type of a command

  • type <command>

View path of a folder/file

  • type <filename>