top of page

Bash programming


A well-formed Bash script starts with a shebang (#!/usr/bin/bash), which tells the system to use the Bash interpreter . To run it, you need to make the script file executable using the chmod +x command .


Variables and User Input

Access value of variable with a $ sign. To make your scripts interactive, the read command is used to prompt the user for input.

Conditional Logic (if, then, else, fi)

Conditionals allow scripts to make decisions. For example, you can check if a file exists or if a user is root before executing commands . The test command (or [ ]) is used for these checks .


Loops are essential for automating repetitive tasks.

  • for loop: Iterates over a list of items .

  • while loop: Repeats a block of code while a condition is true .

  • until loop: Repeats a block of code until a condition becomes true .


Functions:

Functions let you group reusable pieces of code for better organization, similar to other programming languages .



Key RHEL-Specific Considerations

  • Bash Version and Features: RHEL uses specific versions of Bash. For instance, RHEL 6 included version 4.1, which introduced several important changes compared to earlier versions:

    • =~ Operator Changes: The behavior of the regular expression matching operator (=~) in [[ ]] conditional expressions changed. It's recommended to store the regex pattern in a variable to avoid issues .


  • set -e Behavior: The set -e option (which makes the script exit on error) is more aggressive and can cause a script to exit if any command in a pipeline fails .

  • Compatibility Levels: Bash 4.0 introduced compatibility options (compat31) via the shopt builtin, allowing you to revert to the behavior of older versions for specific tasks .


Practical Scripting Examples for RHEL

Here are some basic scripts illustrating common tasks.

  1. A Simple System Info ScriptThis script, when made executable (chmod +x), will display system information .


bash

#!/usr/bin/bash

echo "Hello, this is my first RHEL script."

echo "Listing block devices:"

lsblk

echo "Filesystem free space:"

df -h

  1. Using a for Loop to Retrieve HostnamesThis script demonstrates a for loop, automating the hostname command with different options .

bash

#!/usr/bin/bash

for OPTION in "" "-f" "-s"; do

  echo "Getting hostname with option: ${OPTION}"

  hostname ${OPTION}

  echo "------------------------"

done

  1. A Conditional Check for Script ArgumentsThis is a common pattern to ensure a script has received the correct input (e.g., a filename) .

bash

#!/usr/bin/bash

if [ $# -ne 1 ]; then

   echo "Usage: $0 <filename>"

   exit 1

fi

echo "The argument is: $1"

The official RHEL documentation and man pages (man bash, man test) are your best resources for detailed information on built-in commands and syntax specifics .



Cheatsheet for Bash



File & Directory Operations

Command

Description

pwd

Print current working directory

ls

List files (-l long, -a all, -lh human-readable)

cd

Change directory (cd ~ home, cd - previous)

mkdir

Create directory (-p create parents)

rmdir

Remove empty directory

rm

Remove files (-r recursive, -f force)

cp

Copy files/dirs (-r recursive)

mv

Move/rename files/dirs

touch

Create empty file or update timestamp

ln -s

Create symbolic link



File Content Viewing

Command

Description

cat

Display entire file

less

View file page by page (/ search, q quit)

head

Show first 10 lines (-n 20 for 20 lines)

tail

Show last 10 lines (-f follow live updates)

grep

Search inside files (-i case-insensitive, -r recursive)



Permissions & Ownership

Command

Description

chmod

Change file permissions (chmod 755 script.sh)

chown

Change file owner (chown user:group file)

umask

Set default permissions for new files

Permission numbers: 4=read, 2=write, 1=executeExample: 755 = owner:rwx, group:r-x, others:r-x


Process Management

Command

Description

ps

Show processes (ps aux for all)

top / htop

Interactive process viewer

kill

Terminate process by PID (-9 force kill)

killall

Kill all processes by name

jobs

List background jobs

fg

Bring job to foreground

bg

Resume job in background

&

Run command in background (command &)

nohup

Run command immune to hangups


Package Management (RHEL)

Command

Description

dnf install <pkg>

Install package

dnf remove <pkg>

Remove package

dnf update

Update all packages

dnf search <term>

Search for package

dnf info <pkg>

Show package info

rpm -ivh <file.rpm>

Install local RPM

rpm -qa

List all installed RPMs


Network Commands

Command

Description

ping

Test network connectivity

curl

Transfer data from/to server

wget

Download files

ss

Socket statistics (replaces netstat)

ip a

Show IP addresses (replaces ifconfig)

hostname

Show/change hostname (-I for IP)

dig / nslookup

DNS lookup


User Management

Command

Description

whoami

Show current user

id

Show user/group IDs

sudo

Run command as root

su -

Switch to root user

useradd

Create new user

passwd

Change password

who

Show logged-in users


Bash Built-in Syntax

Variables

bash

VAR="value"              # Set variable

echo $VAR                # Access variable

echo ${VAR}              # Safer access

read VAR                 # Read user input into variable

Conditionals (if)

bash

if [ condition ]; then

    # code

elif [ condition ]; then

    # code

else

    # code

fi


Common test conditions:

Condition

Meaning

[ -f file ]

File exists

[ -d dir ]

Directory exists

[ -z string ]

String is empty

[ -n string ]

String is not empty

[ "$a" = "$b" ]

Strings equal

[ "$a" != "$b" ]

Strings not equal

[ $a -eq $b ]

Integers equal

[ $a -ne $b ]

Integers not equal

[ $a -lt $b ]

Less than

[ $a -gt $b ]

Greater than

[ -e file ]

File exists (any type)

[ -x file ]

File is executable

Loops

bash

# For loop

for item in list; do

    echo $item

done


# For loop with range

for i in {1..10}; do

    echo $i

done


# While loop

while [ condition ]; do

    # code

done


# Until loop

until [ condition ]; do

    # code

done

Case Statement

bash

case $VAR in

    pattern1)

        # code

        ;;

    pattern2)

        # code

        ;;

    *)

        # default code

        ;;

esac

Functions

bash

function_name() {

    local var="local scope"   # Local variable

    echo "Hello $1"           # $1 = first argument

    return 0                  # Return exit code

}

function_name "John"          # Call function


Special Variables

Variable

Description

$0

Script name

$1-$9

Positional arguments

$#

Number of arguments

$@

All arguments as separate words

$*

All arguments as one string

$?

Exit code of last command

$$

PID of current shell

$!

PID of last background command



Arithmetic Operators


$((5 + 3))          # Addition

$((10 - 4))         # Subtraction

$((6 * 7))          # Multiplication

$((20 / 5))         # Division

$((10 % 3))         # Modulo

Logical (within [[ ]])

Operator

Meaning

&&

AND

||

OR

!

NOT

==

Pattern match

=~

Regex match


Keyboard Shortcuts

Shortcut

Action

Ctrl+C

Interrupt/kill current command

Ctrl+Z

Suspend current command

Ctrl+D

Exit shell/EOF

Ctrl+L

Clear screen

Ctrl+A

Move to beginning of line

Ctrl+E

Move to end of line

Ctrl+U

Delete from cursor to beginning

Ctrl+K

Delete from cursor to end

Ctrl+R

Reverse search history

!!

Repeat last command

!$

Last argument of previous command

!n

Run command number n from history


 Text Processing (One-liners)

Command

Description

echo "text" | wc -l

Count lines

echo "text" | wc -w

Count words

echo "text" | sed 's/old/new/g'

Replace text

echo "text" | awk '{print $1}'

Print first column

sort file

Sort lines

uniq

Remove duplicates (needs sort)

cut -d: -f1 /etc/passwd

Extract first field (delimiter :)


Common RHEL Script Patterns

Check if running as root:

bash

if [ $EUID -ne 0 ]; then

    echo "This script must be run as root"

    exit 1

fi

Check if a file exists:

bash

if [ -f "/etc/myconfig.conf" ]; then

    echo "Config exists"

else

    echo "Config missing"

fi

Loop through all .conf files:

bash

for file in /etc/*.conf; do

    echo "Processing $file"

done

Get script directory (reliable method):

bash

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"



Quick Reference: test vs [[ ]]

Syntax

When to use

[ ]

POSIX-compatible, simple tests

[[ ]]

Bash-specific, more features (regex, pattern matching)

(( ))

Arithmetic evaluation

Prefer [[ ]] in Bash scripts for better safety and features.







 
 
bottom of page