Shell

A shell is an interface to the operating system. It accepts some commands from the user and executes programs based on those commands. It is an environment where a user can run scripts or commands. There are various types of shells. In the UNIX world, we could categorize them into 2 major types: The Bourne Shell and the C Shell. Both of them have some subcategories:

Categories of Bourne Shells:
    - Bourne Again Shell (bash)
    - POSIX shell (sh)
    - Korn Shell (ksh)
    
Categories of C Shells:
    - TENEX/TOPS C Shell (tcsh)
    - C Shell (csh)
You can find out which of the shells are available in your system by using the which command:
# Find out various Shell types available in your system
which bash
which ksh
which csh
which sh
which tcsh
You can change to a different shell by simply typing the name of the shell. For example:
sh
bash
ksh
csh
tcsh
Here are some notes for the bash shell
Concept Symbol Description
Shebang #!/usr/bin/env bash
Comment #
Command Separator ;
Terminator ;;
Dot .
Partial Quoting "
Full Quoting '
Comma Operator ,
Escape \
Separator /
Command Substitution `
Null Command :
Redirection Operator >
Bang !
Wild Card *
Test Operator ? Also serves as a wild card, representing one character
Variable Substitution $ Contents of a variable
Parameter Substitution ${}
Quoted Stringing Expansion $' ... '
Positional Parameters $*, $@
Exit Status Variable $?
Process ID Variable $$ Holds the process ID of the script in which it appears
Command Group () Listing commands within () starts a subshell whose variables are not visible to parent process
Braces Expansion {x, y, z}
Block of Code {} Block of code
Test: []
Test: [[]]
Redirection: command > filename Redirects both stdout and stderr of command to filename
Redirection: command >&2 filename Redirects output of command to stderr
Redirection: command >> filename Appends the output of command to filename, creates file if not already exists
Pipe | Passes the stdout of a previous command to the input stdin of the next one
Force Redirection >| Forcibly overwrite an existing file
Tilde ~ $HOME
Current Working Directory ~+ $PWD
Previous Working Directory ~- $OLDPWD
Regular Expression Match =~
Beginning of Line ^
Uppercase Conversion ^, ^^
A simple shell script
#!/usr/bin/env bash
NAME="krsna"
LENGTH=${#NAME}
echo "Hello $NAME"
echo "Your name is $LENGTH characters long"
exit $?
Conditional execution
git commit -m "This is a commit message" && git push
git push || echo "git push failed!"
Parameter expansions
name="Krsna"
echo ${name}        # "Krsna"
echo ${name/K/k}    # "krsna" (substitution)
echo ${name:0:2}    # "Kr" (slicing)
echo ${name::4}     # "Krsn" (slicing)

STRING="/path/to/shellscript.sh"

echo ${STRING%.*}      $ shellscript  (filename only)
echo ${STRING##*/}     # shellscript.sh (filename with extension only)
echo ${STRING##*.}     # sh (extension only )
echo ${STRING%.sh}     # /path/to/shellscript without extension
echo ${STRING%.sh}.o   # /path/to/shellscript.o change extension
echo ${STRING#*/}      # path/to/shellscript.sh with extension
echo ${STRING/shellscript/replacementtext}   # /path/to/replacementtext.sh # search for shellscript and replace with replacementtext
Substitution
${STRING%suffix}	Remove suffix
${STRING#prefix}	Remove prefix
${STRING%%suffix}	Remove long suffix
${STRING##prefix}	Remove long prefix
${STRING/from/to}	Replace first match
${STRING//from/to}	Replace all
${STRING/%from/to}	Replace suffix
${STRING/#from/to}	Replace prefix
Loops
# Simple for loop
for i in ~/Downloads/.*; do
  echo $i
done

# Forever loop
while true; do
  ···
done

# Ranges
for i in {1..10}; do
    echo "This is: $i"
done

# For loop with step size (go from 0 to 100 with step size of 10)
for i in `seq 0 10 100`;do
    echo $i;
done

# Reading lines from a file
cat some_file.txt | while read line; do
  echo $line
done
Functions
function do_something() {
    echo "Hello I am doing something with argument 1: $1"
}
do_something "first argument"

$# = number of arguments
$* = all arguments
$@ = all arguments starting from first
$n = nth argument where n is an integer
Conditions
[ -z STRING ]	        Empty string
[ -n STRING ]	        Not empty string
[ NUM -eq NUM ]	        Equal
[ NUM -ne NUM ]	        Not equal
[ NUM -lt NUM ]	        Less than
[ NUM -le NUM ]	        Less than or equal
[ NUM -gt NUM ]	        Greater than
[ NUM -ge NUM ]	        Greater than or equal
[[ STRING =~ STRING ]]	Regexp
(( NUM < NUM ))	        Numeric conditions
[ -o noclobber ]	If OPTIONNAME is enabled
[ ! EXPR ]	        Not
[ X ] && [ Y ]	        And
[ X ] || [ Y ]	        Or
File Conditions
[ -e FILE ]	            Exists
[ -r FILE ]	            Readable
[ -h FILE ]	            Symlink
[ -d FILE ]	            Directory
[ -w FILE ]	            Writable
[ -s FILE ]	            Size is > 0 bytes
[ -f FILE ]	            File
[ -x FILE ]	            Executable
[ FILE1 -nt FILE2 ]	    1 is more recent than 2
[ FILE1 -ot FILE2 ]	    2 is more recent than 1
[ FILE1 -ef FILE2 ]	    Same files

# String
if [ -z "$some_string" ]; then
  echo "some_string is empty"
elif [ -n "$some_string" ]; then
  echo "some_string is not empty"
fi

# Combinations
if [ THIS ] && [ THAT ] && [ THOSE ]; then
  ...
fi

# Regex
if [[ "regex" =~ "." ]]

if (( $x < $y ))

if [ -e "file.csv" ]; then
  echo "file.csv exists"
fi
Arrays
# Simple array example
declare -a numbers
numbers=(one two three four five six seven eight)
echo ${numbers[0]}                      # First Element
echo ${numbers[@]}                      # All item of array numbers separated by space
echo ${#numbers[@]}                     # Number of elements
unset numbers[2]                        # Remove one item

arpscache=($(arp -an | grep -v incomplete))
echo ${arpscache[0]}           # First Element
echo ${arpscache[@]}           # All item of array arpscache separated by space
echo ${#arpscache[@]}          # Number of elements

# operations
arpscache=("${arpscache[@]}" "10.0.0.12")        # Push
unset arpscache[2]                               # Remove one item
duplicate=("${arpscache[@]}")                    # Duplicate
lines=(`cat "somefile.txt"`)                     # Read from file

# iteration
for i in "${some_array[@]}"; do
  echo $i
done
References:
Advanced Bash-Scripting Guide. (n.d.). Retrieved from https://www.tldp.org/LDP/abs/html/
@rstacruz “Bash Scripting Cheatsheet.” Devhints.io Cheatsheets, devhints.io/bash.