Bash is a command language interpreter. It is the default command interpreter on most GNU/Linux systems. The name is an acronym for the ‘Bourne-Again SHell’.
Scripting allows for automatic command execution that would otherwise take many manually executed interactive steps.
Bash aliases
- shortcuts to bash commands
- syntax
alias name="command"
Intro to bash shell scripting
- The check with shell
echo $SHELL
OR
echo $0
- To list all available shells
>~ cat /etc/shells
# Pathnames of valid login shells.
# See shells(5) for details.
/bin/sh
/bin/bash
/usr/bin/git-shell
/bin/zsh
/usr/bin/zsh
- Basic Shell Script anatomy
#!/bin/bash for bash
# Always starts with a shebang
# This is a comment
echo "Hello, World!"
- For python the shebang will be
#!/usr/bin/python
Running scripts
- Make the script executable
chmod +x script_namechmod 700 script_name
- Run the script with
bash script_name.sh(runs without execute permission)./script_name.sh- For python
python3 script_name.sh(runs without execute permission) source script_name.sh(execute permission is not required)./runs the script in sub shell and calling it runs in current shell- when run by calling a program binary, it overrides the shebang
Variables in Bash
- A name for a memory location
- Anatomy : name_of_variable assignment_operator value_of_variable
os=Linux|os = Linuxis not allowed : no spaces- if there is a space in variable value, enclose it with
""
os="Debian Bullseye"
-
Bash is a weakly typed, no type declaration
-
In bash, numbers are only integers no floating points numbers
version=11
-
variable names cannot start with a
- space
- number
- Cannot have
.in a name@in a name
-
variable names can however have with
_- This is okay: server_name:“Apache 2.4”
-
the value of the variable can be referenced using
$variable_nameecho $osecho "I am learning $os"- Note: While referencing variable in string, make sure to use
""and not''> echo "I am learning $os" I amlearning Linux
-
NOTICE THE DIFFERENCE with
""and''> echo 'I am learning $os' I am learning $os -
\$can be used as an escape character to reference variable names instead of variable values.> echo "The value of \$os is $os" The value of $os is Linux -
Use keyword
setto list all the shell variables and pipe it tolessorgrepdepending on the use case. -
Use keyword unset to remove a variable
-
good practice to keep user defined variables names in lower case letters so there is no conflict with env variables
-
use
declarekeyword with-rflag to create a read only variabledeclare -r logdir="/var/log"- use case
ls $logdir- reassignment is not allowed
> logdir=abc bash: logdir: readonly variable
Environment Variables
Each time we launch a terminal window and a shell inside it, a collection of predefined variables are set with dynamic values which are used to customize how a system works. There are two class of such variables
-
Environment Variables
- defined for the current shell
- inherited by a child shells or processes
- used to pass information to processes
- displayed using
envorprint env - Some built in environment variables
$PATH: path variable$USER: Current logged in user$HOME: Home directory of$USER$HISTFILE: Shell command history file$HISTSIZE: Max length of$HISTFILE
- The names are UPPERCASE
- To create an new env variable,
exportit in a startup config like.bashrc - To and to path:
export PATH=$PATH:/path_to_dir/ - To add a new:
export MYVAR=value
-
Shell Variables
- contained exclusively within the shell in which they were set or defined
- displayed using
set
-
Configuration
- user: .bashrc
- system-wide:
/etc/bash.bashrcand/etc/profile
Getting user Input
- Keyword
read: read from standard input into shell variables
> read name
enter_name_here
- A variable named name is created with the input value
- use
-pflag to echo a prompt or hint
> read -p "Enter your name please: " name
enter_name_here
- Access name by
$namelikeecho $name - use
-sto hide the user input, for example a password.
Special Variables & Positional Arguments
-
Context
- In
apt install neofetch,installis the first argument in the script andneofetchis the second argument. - They are separated by a
spacereferred to as inter field separators.
- In
-
Example: In
./script.sh filename1 dir1 some_value other_value- $0 is the name of the script : script.sh
- $1 is the first positional argument : filename1
- $2 is the second positional argument : dir1
- $4 is the last positional argument : other_value
- $9 would be the 9th positional argument and so on
- $# is the number of positional arguments
- ”$*” is the string representation of all positional arguments
- $? is the most recent foreground command exit status
Flow Control
Logic Statements
If, Elif and Else Statements
- Anatomy of an if, elif, else statement
- NOTE: double
[[ ]]is a newer safer way to do test conditions as it works well with strings with spaces and allows for regex matching. But it also works with[]
- NOTE: double
if [[ this_condition_is_true ]]
then
execute_this_code
elif [[ some_ther_condition_is_true ]]
then
execute_this_code
else
execute_this_code
fi
- The man page for test contains all the test condition allowed in an if statement
- check the man page for more.
- Some common conditions
-fis a file-dis a directory
Testing conditions for numbers
- Some common testing conditions for numbers
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
- Example
#!/bin/bash
read -p "Enter and number: " guess
if [[ $guess -eq 5 ]]
then
echo "Jackpot"
else
echo "Okay looser!"
fi
- Some testing operations for strings
-n STRING
the length of STRING is nonzero
STRING equivalent to -n STRING
-z STRING
the length of STRING is zero
STRING1 = STRING2
the strings are equal
STRING1 != STRING2
the strings are not equal
- Example
#!/bin/bash
read -p "String1: " str1
read -p "String2: " str2
########################
# Method 1
########################
if [ "$str1" = "$str2" ]
then
echo "Equal strings"
else
echo "Not Equal strings"
if
########################
########################
# Method 2
########################
if [[ "$str1" == "$str2" ]]
then
echo "Equal strings"
else
echo "Not Equal strings"
if
########################
- Example: Sub strings
str1="some strings with linux in it."
if [[ '$str1' == *"linux"* ]]
then
echo "The substring linux IS present."
else
echo "The substring linux IS NOT present."
fi
Multiple testing conditions and nested if statements
-
For multiple conditions
- the logical
orandandoperators can be usedoris||andis&&
- syntax
[[ condition 1 ]] && [[ condition 2 ]][[ condition 1 ]] || [[ condition 2 ]]- Alternatively
EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true - the logical
-
Anatomy of a nested if statement
if [[ condition ]]
then
if [[ condition 2]]
then
do_this
else
do_this
else
do_this
fi
For loop (Loops)
- Anatomy of a for loop
for item in LIST
do
COMMANDS
done
- Example: Iterate through a list
#!/bin/bash
for os in Ubuntu CentOS Slackware Kali "MX Linux"
do
echo "OS is $os"
done
- Example: Iterate through a range of numbers
- Specify range
{start_num..end_num} - with step
{start_num..end_num..step
- Specify range
for num in {3..7}
do
echo "num is $num"
done
- Example: Loop through items in a directory.
for item in ./*
do
if [[ -f "$item" ]]
then
echo "$item"
fi
done
While loop (Loops)
- Anatomy of a while loop.
- It runs as long as a specific command is true
while CONDITION_IS_TRUE
do
COMMANDS
done
- Example: Iterate through numbers
i=0
while [[ $i -lt 10]]
do
echo "i: $i"
((i++))
done
- Example: Infinite loop
#!/bin/bash
while true
do
echo "In an infinite loop, press CTRL+C to exit."
sleep 1
done
- alternates
while [[ true ]]while :while true; do echo "infinite loop"; sleep 1; done
Command Substitutions
- To store the output of a command into a variable
# Method 1
var_one=`command`
# Method 2
var_two="$(command)"
- For arithmetic operations use
((arithmetic_operation))
Case Statements
- Its a simpler alternative to if,elif,else
- It is similar to
switchstatement in C, C++ & Java - Anatomy of the a
casestatementPATTERNcan contain special charactersSTATEMENTblocks end with;;(double semicolon)*PATTERN is a default case
case EXPRESSION in
PATTERN_1)
STATEMENTS
;;
PATTERN_2)
STATEMENTS
;;
PATTERN_3)
STATEMENTS
;;
PATTERN_4)
STATEMENTS
;;
""
""
*)
STATEMENTS
;;
esac
- Example
- Multiple options in case
option_1|option_2 - Enclose
"A String With Spaces"inside""
- Multiple options in case
#!/bin/bash
echo -n "Enter your favorite pet: "
read PET
case "$PET" in
dog)
echo "Your favorite pet is the dog."
;;
cat|Cat)
echo "You like cats."
;;
fish|"African Turtle")
echo "Fish or turtles are great."
;;
*)
echo "Your favorite pet is weird"
esac
- Example: Managing processes
signal.sh
#!/bin/bash
if [[ $# -ne 2 ]]
then
echo "Run the script with 2 arguments: Signal and PID."
exit
fi
case "$1" in
1)
echo "Sending the SIGHUP signal to $2"
kill -SIGHUP $2
;;
2)
echo "Sending the SIGINT signal to $2"
kill -SIGINT $2
;;
15)
echo "Sending the SIGTERM signal to $2"
kill -15 $2
;;
*)
echo "Signal number $1 will not be delivered"
esac
Functions in Bash
- Used to organize code
- modularity
- reusability
- Compared to other programming languages, bash functions are limited.
- Anatomy of a bash function
- the
()in functions definitions are purely decorative- they do not take any arguments in them
- the arguments can be passed into functions similar to command line arguments, i.e., refer to the variable or arguments with
$varibale_nameor$1$2etc. - bash functions do not allow a return value
- the
#!/bin/bash
function name_of_function () {
one thing to do
two thing to do
}
OR
name_of_function () {
do_something
}
# This is a function call
name_of_function
Variable scope in function
- By default in bash all variables are global
- To declare a local variable inside a function, use the keyword
local
var1-"AA"
var2="BB"
func1() {
var1="XX"
local var2="YY"
echo "Inside func1: var1=$var1, var2=$var2"
}
func1
echo "Outside func1: var1=$var1, var2=$var2"
- Output from above
Inside func1: var1=XX, var2=YY
Outside func1: var1=XX, var2=BB
Menus in bash; The Select Statement
- Anatomy of a select statement
- ITEM is a user defined variable
- LIST is a series of strings or output of commands
- if a
"string contains a space"enclose it in""
- if a
- The selection is stored in a predefined variable
REPLY - The default prompt is
#?and can be change by setting a predefined variablePS3
select ITEM in LIST
do
COMMANDS
done
- Example
#!/bin/bash
PS3="Choose your country"
select COUNTRY in India Germany France USA "United Kingdom" Quit
do
case $REPLY in
1)
echo "You speak many languages"
;;
2)
echo "You speak many languages"
;;
3)
echo "You speak many languages"
;;
4)
echo "You just speak amarican english"
;;
5)
echo "You speak many languages"
6)
echo "Qutting..."
break
;;
*)
echo "Invalid Option"
done
