Bourne Again Shell (BASH) Lecture Notes

Bourne Again Shell (BASH)

  • Instructor: Dr. Subharag Sarkar

  • Definition of a Shell: A shell acts as a command interpreter and provides an interface between a human user (or another program) and the Operating System (OS).

  • Core Functions of a Shell:

    • Running programs (e.g., executing the ls program).

    • Providing command-line editing capabilities.

    • Establishing alternative sources of input and destinations for output for programs.

  • The Terminal: This is a program that opens a graphical window to allow user interaction with the shell. It serves as the interface between end users and the Linux system, functioning similarly to command prompts in Windows.

Overview of the Bourne-Again Shell (BASH)

  • Origin: BASH is an extension of the original Bourne Shell (sh).

  • Checking Versions:

    • To find the location: which bash

    • To check the version: bash --version

  • Feature Integration: BASH incorporates useful features from the Korn shell (ksh) and the C shell (csh).

  • C Shell (csh): A command processor typically run in a text window, allowing users to execute typed commands.

  • Other Shell Variants:

    • tcsh

    • zsh

    • csh

    • ksh

  • Purpose of Using a Shell: It is primarily used for routing jobs, such as system administration, without the necessity of writing full programs.

Shell Responsibilities

  • Program Execution: The shell executes all programs requested by the user. Each line is interpreted according to the format: program_name arguments.

    • White space between the program name and individual arguments is ignored.

    • Built-in Commands: Some commands, such as cd, pwd, and echo, are built directly into the shell.

    • Utilities: Other commands are utilities that the shell must retrieve from the disk.

  • Variable and Filename Substitution:

    • The shell allows users to create variables and assign values to them, similar to programming languages.

    • Wildcards (Globbing): The shell uses wildcard characters to generate lists of files to pass to a command. These wildcards are replaced by matching files before the utility receives them. Examples include:

      • * (Matches zero or more of any character).

      • ? (Matches any single character).

      • [...] (Matches any single character within the provided list).

  • I/O Redirection: The shell manages the redirection of input and output by scanning for specific symbols:

    • < (Input redirection).

    • > (Output redirection).

    • >> (Append output redirection).

  • Pipeline Hookup: The shell detects the pipe symbol | to connect the standard output of a preceding command to the standard input of the succeeding command.

  • Environment Control: Users can customize their environment, including the default home directory and the shell prompt cursor.

  • Interpreted Programming Languages: The shell allows for the development of "shell scripts" to automate repetitive tasks. It includes features like variables, arrays, decision-making, loops, and arithmetic operations.

Shell Startup and Processes

  • Login Shell: A shell started at system startup by the init process (or systemd). It requires a username and password to log the user into the system.

  • Non-login Shell: A shell invoked without requiring a login process.

  • Startup Sequence:

    1. Kernel Booting: The initial startup process.

    2. init / systemd: Invoked by the kernel at the end of startup; responsible for starting and shutting down the system. Most modern Linux distributions use systemd to replace init.

    3. getty: Created by init/systemd, it manages the terminal type (tty).

    4. login: Authenticates the user. Once authenticated, the appropriate shell is created.

Shell Metacharacters and Substitutions

  • Metacharacters: Characters with special meanings that must be escaped or quoted to inhibit special behavior:

    • Redirection: < > |

    • Wildcards: * ? [ ]

    • Others: & ; $ ! \ ( ) space tab newline

  • Globbing Examples:

    • ls *.c: Matches all files ending in .c.

    • ls file0?.c: Matches files like file01.c or file0A.c.

    • ls file[0-9].c: Matches files with a single digit in that position.

    • ls [a-zA-Z]*: Matches files starting with any letter.

    • ls [!0-9]*: Matches files that do NOT start with a digit.

Basic Shell Scripting

  • Shell Script Definition: A file containing a series of shell commands.

  • Data and Control Structures: Scripts use variables, arithmetic, functions, branches, and loops.

  • The Shebang: Every script must begin with #! followed by the path to the shell to be executed.

    • Example: #!/bin/bash

  • File Extension: Usually ends in .sh (e.g., hello.sh).

  • Execution Steps:

    1. Make the script executable: chmod +x hello.sh

    2. Invoke the script: ./hello.sh

Practice Task I: Informational Script

  • Script Content:

#!/bin/bash
echo "You are logged in as ($USER) to machine (`uname -n`)."
echo "This month’s calendar is:"
cal
echo "You are currently running the following processes:"
ps u
  • Note on ps: Stands for "Process Status," a utility used to view information about running processes.

Subshells and Environment Variables

  • Subshell Definition: A child process launched by a shell or shell script.

    • Each subshell has its own environment.

    • Variables in a subshell are destroyed upon exit and cannot change variables in the parent shell.

  • Creating Subshells:

    • Executing the bash command.

    • Starting background processes.

    • Running a shell script.

    • Grouping commands in parentheses: pwd; (cd /; pwd); pwd

  • Variable Types:

    • Local Variables: Defined within the current shell.

    • Environment Variables: Set by the system (e.g., $USER).

  • The env Command: Used to display or modify the current environment.

    • Syntax: env [options] [varname=value] [command]

    • Example: env MYVAR="Hello" bash -c 'echo $MYVAR'

The $PATH Variable

  • Purpose: Contains a colon-separated list of directories where the shell searches for executable commands (e.g., ls, python).

  • Modification: To add a directory to the search path:

    • PATH=$PATH:$HOME/bin

    • export PATH

  • Unsuccessful Search: Returns a "command not found" message.

  • Example Extension: To add /usr/programs/bin, use PATH=$PATH:$HOME/bin:/usr/programs/bin.

Variable Structure and Exporting

  • Local Variable Syntax: varname=value

    • Must begin with alphabetical characters or an underscore.

    • Spaces are not allowed around the = sign.

    • Case-sensitive.

    • Do not use wildcards (*, ?) in names.

    • Access value using the $ prefix: echo $score.

  • Exported Variables: Values can be passed to subshells using the export command.

    • Caution: Changing an exported variable in a subshell does not affect the parent shell's value.

    • The command export with no arguments lists all currently exported variables.

    • unset is used to destroy a variable.

Command Line Arguments and User Input

  • Positional Parameters: Command-line arguments can modify script behavior.

    • $1, $2, $3, ... $N: Refer to specific arguments.

    • $*: Refers to all arguments.

    • $#: Count of arguments.

    • The set command can manually assign values to these parameters (e.g., set tim bill ann fred).

  • User Input: The read command prompts and stores input.

    • Syntax: read [var1] [var2] or read -p "prompt" [var1].

    • If more input is provided than variables, the remainder is assigned to the last variable.

Quoting Mechanisms

  • Backtick (`): Performs command substitution (e.g., `uname`).

  • Double Quotes ("): Allows variable expansion but prevents wildcard expansion.

  • Single Quote ('): Prevents both wildcard replacement and variable/command substitution (literal interpretation).

  • Backslash (\): Preserves the literal value of the single character immediately following it.

  • Expansion Rules:

    • echo *: Expands to all files.

    • echo "*": Does not expand wildcards.

    • echo "$HOME": Expands the variable.

    • echo '$HOME': Does not expand the variable.

Arithmetic and Condition Expressions

  • Arithmetic Evaluation:

    • Use the let statement: let X=10+2*7.

    • Operators: +, -, *, /, %.

    • Alternative syntax: $[expression] or $((expression)).

  • Conditionals:

    • if [ expression ]; then ... elif ... else ... fi.

    • Single Brackets [ ... ]: Alias for the test command.

    • Double Brackets [[ ... ]]: BASH keyword; supports C-like syntax and relational operators. Not supported by all shells.

The test Operators

  • File Operators:

    • -d file: True if file is a directory.

    • -f file: True if file is an ordinary file and exists.

    • -r file: True if readable.

    • -s file: True if file is not empty.

    • -w file: True if writable.

    • -x file: True if executable.

    • -O file: True if owned by user.

  • Relational Operators (Numeric):

    • -gt: Greater than.

    • -ge: Greater than or equal to.

    • -lt: Less than.

    • -le: Less than or equal to.

    • -eq: Equal.

    • -ne: Not equal.

  • String Operators:

    • < / >: String comparison.

    • -n str: String length is greater than zero.

    • -z str: String length is zero.

  • Logical Operators:

    • !: Negation.

    • -a: Logical AND (used in [ ]).

    • -o: Logical OR (used in [ ]).

    • && and ||: Logical AND/OR (must be used in [[ ]]).

Case Statement

  • Purpose: Handles decisions based on multiple choices.

  • Syntax:

case value in
  pattern1) 
    statements ;;
  pattern2|pattern3)
    statements ;;
  *)
    statements ;;
esac
  • The first matching pattern executes. The * pattern acts as a default/catch-all.

Practice Tasks and Solutions

  • Task II (Score Check):

#!/bin/bash
read -p "Enter your score: " score
if [ $score -ge 90 ]; then
    echo "Excellent"
elif [ $score -ge 70 ]; then
    echo "Good"
else
    echo "Needs Improvement"
fi
  • Task III (Age-based Rates using Case):

#! /bin/bash
ChildRate=3
AdultRate=10
SeniorRate=7
read -p "Enter your age: " age
case $age in
  [1-9]|[1][0-2])  # age 1 - 12
    echo "Your rate is $ChildRate.00" ;;
  [1][3-9]|[2-5][0-9])  # age 13 - 59
    echo "Your rate is $AdultRate.00" ;;
  [6-9][0-9])  # age 60+
    echo "Your rate is $SeniorRate.00" ;;
esac