Personal

Sr. Developer

View on GitHub
8 March 2020

Bash 101

by

Overview

A Unix shell is a command-line interpreter or shell that provides a command line user interface for Unix-like operating systems. The shell is both an interactive command language and a scripting language, and is used by the operating system to control the execution of the system using shell scripts.

— Unix shell
https://en.wikipedia.org/wiki/Unix_shell

Hello World

hello_world.sh
#!/bin/bash
read -p "Your Name? " name

echo "Hello World $name!"
chmod a+x ./hello_world.sh
bash-3.2$ ./hello_world.sh
Your Name? Mike
Hello World Mike!
bash-3.2$

Programming Paradigm

Bash script is an imperative, procedural, scripting programming language.

Procedural Programming

Procedural programming is a programming paradigm, derived from structured programming,[citation needed] based on the concept of the procedure call. Procedures, also known as routines, subroutines, or functions, simply contain a series of computational steps to be carried out.

— Procedural Programming
https://en.wikipedia.org/wiki/Procedural_programming

The essence procedural programming is Data and Procedure.

Bash implements Data in Variable, Procedure in Function.

Variables

Unlike many other programming languages, Bash does not segregate its variables by "type." Essentially, Bash variables are character strings, but, depending on context, Bash permits arithmetic operations and comparisons on variables. The determining factor is whether the value of a variable contains only digits.

— https://www.tldp.org/LDP/abs/html/untyped.html

Basically, Bash is dynamic typing. Variable could be assigned any type of value. Additionally, it does implicitly type conversion based on context.

bash-3.2$ a=12 # assign integer value to variable a
bash-3.2$ echo $a # variable a is referring integer value
12
bash-3.2$ a=string # assign string value to vairable a
bash-3.2$ echo $a # variable a is referring string value
string
bash-3.2$ b=23 # assign integer value to variable a
bash-3.2$ echo $a+$b # convert integer value to string value implicitly when add string by integer
string+23
Variable Assignment and Substitution

TBD

Variable Kind

Int bash, there are three kinds of variables:

  • Local Variables, variables visible only within a code block or function

  • Environment Variables, variables which affect the behavior of the shell and user interface

  • Positional Variables, arguments passed to the script from the command line: $0, $1, $2, $3 …​

Value Type

Bash built in value types:

  • numeric

  • string

  • array

Numeric

TBD

String

TBD

Array

TBD

Function

Function is defined by keyword function. It can not define arguments in function signature, but it is still able to pass and refer arguments. Arguments could be referred by positional variables $1, $2, $3, …​ in function scope. The positional variable $0 is function name, arguments start at $1. Function is not able to return actual value, but it could simulate return by echo.

Function example:

#!/bin/bash

factorial()
{
    if (( $1 <= 1 )); then
        echo 1
    else
        last=$(factorial $(( $1 - 1 )))
        echo $(( $1 * last ))
    fi
}
factorial $1

Control Flow

Branching

There are two approaches to implement branching in Bash script:

  • if/then

  • case

if/then

if/then is a two way branching (if/then is called test most time). The form of if/then is:

if [ condition ]
then
    command
else
   command
fi

If condition is true, it executes then branch; if condition is false, it executes else branch. For example:

if [ $1 -lt "10" ]
then
    echo "input $1 is less than 10"
else
    echo "input $1 is not less than 10"
fi

if/then could nest if/then, for example:

if [ $1 -lt "10" ]
then
    echo "input $1 is less than 10"
elif [ $1 -lt "20" ]
then
    echo "input $1 is not less than 10 but less than 20"
else
    echo "input $1 is not less than 20"
fi

case

case is a multiple branching. The form is:

case "$variable" in

condition1)
command1
;;

condition2)
command2
;;

esac

Example:

case $1 in
    "10")
        echo "input $1 is 10"
        ;;
    "20")
        echo "input $1 is 20"
        ;;
    "30")
        echo "input $1 is 30"
        ;;
    *)
        echo "input $1 other than 10, 20 or 30"
esac

Loops

A loop is a block code that iterates a list of commands as long as the loop control condition is ture.

There are three approaches to implement loop in Bash script:

  • for loop

  • while

  • until

for loop

The form of for loop is:

for arg in [list]
do
  commands
done

During each pass through the loop, arg takes on the value of each successive variable in the list.

For example:

## for loop
for v in "zero" "one" "two" "three" "four" "five"
do
    echo "found value $v"
done

for loop also could inerate array:

list=( "zero" "one" "two" "three" "four" "five" )

for v in "${list[@]}"
do
    echo "found value $v"
done

while

The form of while is:

while [ condition ]
do
  commands
done

This construct tests a condition on the top of loop, and keeps loop as long as that condition is true.

For example:

## while

count=0
limit=10

while [ "$count" -lt "$limit" ]
do
    echo "count is $count, has not reached limit $limit"
    (( count += 1 ))
done

echo "count is $count, has reached limit $limit"

until

The form of until is:

until [ condition ]
do
  commands
done

This construct tests for a condition on the top of a loop, and keeps loop as long as that condition is false.

For example:

## until

count=0
limit=10

until [ "$count" -gt "$limit" ]
do
    echo "count is $count, has not reached limit $limit"
    (( count += 1 ))
done

echo "count is $count, has reached limit $limit"

Tests

If file exists?

# if file exists

if [ -e "$1" ]
then
    echo "$1 exists"
else
    echo "$1 does not exist"
fi

If file older than?

TBD

Has file been changed recently?

TBD

Batch Text Editing

Bash itself is not capable of batck test editing. It’s commonly implemented by comandline tools sed and awk.

Sed

Sed is a non-interactive stream editor. It receives text input, whether from stdin or from a file, performs certain operations on specified lines of the input, one line at a time, then outputs the result to stdout or to a file.

Awk

Awk is a full-featured text processing language with a syntax reminiscent of C. While it possesses an extensive set of operators and capabilities, we will cover only a few of these here - the ones most useful in shell scripts.

Awk breaks each line of input passed to it into fields. By default, a field is a string of consecutive characters delimited by whitespace, though there are options for changing this. Awk parses and operates on each separate field. This makes it ideal for handling structured text files — especially tables — data organized into consistent chunks, such as rows and columns.

Batch Replace

example.txt
It earns 1,000 in Q1, totally 5,000 in this year.
It earns 1,500 in Q2, totally 5,000 in this year.
It earns 1,750 in Q3, totally 5,000 in this year.
It earns 750 in Q4, totally 5,000 in this year.

Replace all 'earns' by 'losts'.

sed 's/earns/losts/g' example.txt
It losts 1,000 in Q1, totally 5,000 in this year.
It losts 1,500 in Q2, totally 5,000 in this year.
It losts 1,750 in Q3, totally 5,000 in this year.
It losts 750 in Q4, totally 5,000 in this year.

List Recent Changed Files

TBD

tags: bash - linux - script