Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Linux Shell Command Line and Scripting Fundamentals

Tech Oct 16 10

Overview of Shell Environments

The default interactive shell across most Linux distributions is GNU Bash (Bourne Again Shell). This article focuses on Bash capabilities while acknowledging alternative shells:

  • ash: Lightweight, Bash-compatible shell designed for minimal resource usage
  • korn (ksh): Programming-oriented shell maintaining Bourne shell compatibility
  • tcsh: Enhanced C shell incorporating C language syntax elements
  • dash: Debian Almquist Shell, a direct descendant of ash
    • Default on Debian and Ubuntu systems for system scripts
    • Minimalist design with fewer built-in features than Bash
    • Lacks arithmetic expansion, advanced test constructs, and function declarations
  • zsh: Feature-rich hybrid combining Bash, Korn, and tcsh capabilities
    • Highly customizable with loadable modules
    • Superior shell option handling and compatibility modes
    • Native floating-point arithmetic support

Accessing the Command Line Interface

Before graphical desktops, the Command Line Interface (CLI) was the primary system interaction method.

Console Terminals

Linux provides virtual consoles—terminal sessions running in memory. Most distributions configure 6-12 virtual consoles accessible via Ctrl+Alt+F1 through Ctrl+Alt+F12. Note that graphical programs cannot run in these text-mode consoles.

Console appearance customization:

# Invert screen colors
setterm --inversescreen on
setterm --inversescreen off

# Change background/foreground colors
setterm -background blue
setterm -foreground yellow

# Reset to defaults
setterm -reset

Graphical Terminal Emulators

Modern desktop environments offer terminal emulator applications including:

  • Alacritty, Kitty (GPU-accelerated)
  • GNOME Terminal, Konsole (desktop integrated)
  • xterm, rxvt-unicode (classic X11)
  • Terminator, Tilix (tiling/multiplexing)

Shell Session Initialization

The shell program launched upon login is configured in /etc/passwd. Interactive shells display a prompt (typically $ for regular users, # for root) and start in the user's home directory.

Documentation Access

The man command provides comprehensive command documentation:

man command_name
man -k keyword  # Search by keyword
man 5 passwd    # Section-specific lookup

Manual sections:

  1. Executable programs and shell commands
  2. System calls
  3. Library functions
  4. Special files
  5. File formats and conventions
  6. Games
  7. Miscellaneous concepts
  8. Administrative commands
  9. Kernel routines

Essential Command Syntax

Command structure follows this pattern:

COMMAND [OPTIONS]... [ARGUMENTS]...

Core Navigation and File Operations

  • cd: Change directory (supports absolute and relative paths)
  • pwd: Print working directory
  • ls: List directory contents with pattern matching
  • touch: Create empty files or update timestamps
  • mkdir: Create directories
  • ln: Create hard or symbolic links
  • cp: Copy files/directories (-R for recursive)
  • mv: Move/rename files (preserves inode and timestamps)
  • rm: Remove files/directories (-r for recursive)

File Content Examination

  • file: Determine file type by analyzing content
  • cat: Concatenate and display entire file contents
  • more: Paginated viewing (forward-only)
  • less: Enhanced pager with backward navigation and search
  • tail: Display last 10 lines (-n N for custom count)
  • head: Display first 10 lines

System Administration Commands

Process Monitoring

ps displays process information with three option styles:

  • Unix-style: ps -ef (all processes, full format)
  • BSD-style: ps aux (user-oriented output)
  • GNU long options: ps --forest (hierarchical display)

top provides real-time process monitoring with interactive commands:

  • f: Select sort field
  • d: Adjust polling interval
  • q: Quit

Process Termination

# Terminate by PID
kill PID
kill -9 PID  # Forceful termination

# Terminate by name
pkill process_name

# Send specific signals
kill -s SIGTERM PID

Storage Management

mount attaches filesystems to the directory tree:

mount -t vfat /dev/sdb1 /mnt/usb
mount -t iso9660 /dev/cdrom /mnt/cdrom

umount detaches storage devices:

umount /dev/sdb1
umount /mnt/usb

df shows disk space usage; du displays directory space consumption.

Data Processing Utilities

  • sort: Sort lines (-t delimiter, -k field, -n numeric)
  • grep: Pattern matching with regular expressions
  • gzip/gunzip: File compression/decompression

Linux System Management

User Account Management

# Create user
sudo useradd -m -s /bin/bash newuser

# Modify user properties
sudo usermod -aG wheel newuser  # Add to supplementary group
sudo passwd newuser             # Set password

# Delete user
sudo userdel -r newuser         # Remove home directory

# Lock/unlock account
sudo usermod -L lockeduser
sudo usermod -U unlockeduser

File Permissions

Permission structure: rwxr-xr-x (owner, group, others)

chmod 755 script.sh      # Octal mode
chmod u+x,g-w file.txt   # Symbolic mode

chown user:group file    # Change ownership
chgrp admin file         # Change group only

umask sets default permissions for new files.

Access Control Lists

# View ACLs
getfacl sensitive_file

# Set ACL entries
setfacl -m u:alice:rw file
setfacl -m g:staff:rwx directory

# Remove ACL entries
setfacl -x u:alice file

Filesystem Management

Partitioning tools:

  • fdisk: MBR partitions (max 2TB)
  • gdisk: GPT partitions
  • parted: Advanced partitioning with resize support

Filesystem creation:

mkfs.ext4 /dev/sdb1
mkfs.xfs /dev/sdc1

LVM (Logical Volume Management):

# Physical volumes
pvcreate /dev/sdb1
pvdisplay

# Volume groups
vgcreate vg_data /dev/sdb1
vgextend vg_data /dev/sdc1

# Logical volumes
lvcreate -L 10G -n lv_home vg_data
lvextend -L +5G /dev/vg_data/lv_home

Package Management

Debian/Ubuntu:

dpkg -i package.deb
apt update
apt install package_name

RHEL/CentOS/Fedora:

rpm -ivh package.rpm
dnf install package_name

Containerized Applications

  • snap: Universal Linux packages with sandboxing
  • flatpak: Desktop application containers

Shell Environment Deep Dive

Shell Types and Identification

  • Login shell: Interactive session started at login
  • Non-login shell: Subshells and script executions
  • Check current shell: echo $0

Subshell Mechanics

Subshells are child processes created when:

  • Explicitly invoking a shell: bash
  • Using command grouping with parentheses: (command1; command2)
  • Running background jobs: command &
  • Creating coprocesses: coproc myprocess

Detect subshell depth via $BASH_SUBSHELL variable.

Command Classification

  • External commands: Separate binaries in /bin, /usr/bin, etc. Execute via forking.
  • Built-in commands: Part of shell binary (e.g., cd, exit, history, alias). Execute without forking.

Verify command type: type command_name

Environment Variables

Variables store session data accessible to programs and scripts.

  • Global variables: Visible to shell and all subshells. View with env or printenv.
  • Local variables: Visible only to creating shell. View with set.
# Assignment (no spaces)
user="alice"
count=42

# Reference
echo "$user"
echo "${count}_items"

# Export as global
export user

# Delete variable
unset count

# Arrays
files=(file1.txt file2.txt file3.txt)
echo "${files[1]}"  # Access second element

Startup File Hierarchy

Login shells process files in this order:

  1. /etc/profile - System-wide configuration
  2. ~/.bash_profile or ~/.bash_login or ~/.profile - User-specific login settings
  3. ~/.bashrc - Interactive shell configuration

Non-login interactive shells only read ~/.bashrc.

Non-interactive shells check $BASH_ENV for initialization scripts.

Shell Scripting Essentials

Script Structure

#!/bin/bash
# Description: Example script demonstrating basic structure

# Variable definitions
source_dir="/var/log"
target_file="summary.txt"

# Command execution
echo "Processing logs from $source_dir" > "$target_file"
ls -l "$source_dir"/*.log >> "$target_file"

Execute scripts by:

  • Adding to PATH: export PATH="$PATH:/path/to/script_dir"
  • Using absolute/relative path: /path/to/script.sh or ./script.sh

Command Substitution

Capture command output into variables:

# Modern syntax (preferred)
current_date=$(date +%Y-%m-%d)
file_count=$(find . -type f | wc -l)

# Legacy backtick syntax
old_style=`hostname`

Input/Output Redirection

# Output redirection
echo "Data" > output.txt      # Overwrite
echo "More" >> output.txt     # Append

# Input redirection
wc -l < input.txt

# Here document
cat << EOF
This is multi-line
text input
EOF

# Pipeline
cat file.txt | grep "pattern" | sort > result.txt

Mathematical Operations

# Integer arithmetic with double parentheses
result=$(( 10 + 5 * 2 ))
echo $result  # Outputs 20

# Using bc for floating-point
pi_value=$(echo "scale=5; 22/7" | bc)
echo $pi_value  # Outputs 3.14285

# Increment/decrement
counter=0
((counter++))
echo $counter  # Outputs 1

Exit Status Codes

Commands return exit status via $?:

  • 0: Success
  • Non-zero: Failure (1-255)
grep "text" file.txt
if [ $? -eq 0 ]; then
    echo "Pattern found"
fi

Control Structures

Conditional Statements

# if-elif-else
if [ -f "$target_file" ]; then
    echo "File exists"
elif [ -d "$source_dir" ]; then
    echo "Directory exists"
else
    echo "Neither exists"
fi

# case statement
case "$action" in
    start)
        start_service
        ;;
    stop)
        stop_service
        ;;
    restart)
        restart_service
        ;;
    *)
        echo "Invalid action"
        ;;
esac

Loop Constructs

# for loop with list
for item in apple banana cherry; do
    echo "Processing: $item"
done

# C-style for loop
for ((i=1; i<=5; i++)); do
    echo "Iteration: $i"
done

# while loop
counter=0
while [ $counter -lt 3 ]; do
    echo "Count: $counter"
    ((counter++))
done

# until loop
until [ $counter -eq 0 ]; do
    echo "Countdown: $counter"
    ((counter--))
done

# Loop control
for num in {1..10}; do
    if [ $num -eq 5 ]; then
        continue  # Skip 5
    fi
    if [ $num -eq 8 ]; then
        break     # Exit at 8
    fi
    echo "$num"
done

Command-Line Arguments

#!/bin/bash
# Script: process_files.sh

echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"
echo "Total arguments: $#"
echo "All arguments: $@"

# Shift arguments
while [ $# -gt 0 ]; do
    echo "Processing: $1"
    shift
done

Input Handling

# Prompt for input
read -p "Enter filename: " target_file
read -s -p "Enter password: " user_pass  # Silent input
echo

# Timeout input
if read -t 5 -p "Continue? (y/n): " response; then
    echo "You entered: $response"
else
    echo "Timeout!"
fi

# Read from file
while read -r line; do
    echo "Line: $line"
done < input.txt

Option Parsing

# Manual parsing
while [ $# -gt 0 ]; do
    case "$1" in
        -v|--verbose)
            verbose=1
            shift
            ;;
        -f|--file)
            config_file="$2"
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

# Using getopts
while getopts ":vf:" opt; do
    case $opt in
        v)
            verbose=1
            ;;
        f)
            config_file="$OPTARG"
            ;;
        \?)
            echo "Invalid option: -$OPTARG"
            exit 1
            ;;
    esac
done

File Descriptors

# Redirect stdout and stderr
exec 1>output.log
exec 2>error.log

# Use custom file descriptor
exec 3<>data.txt
echo "Write to fd3" >&3
cat <&3

# Close descriptor
exec 3>&-

Temporary Files

# Create secure temp file
temp_file=$(mktemp /tmp/temp.XXXXXX)
echo "Temporary data" > "$temp_file"

# Create temp directory
temp_dir=$(mktemp -d /tmp/work.XXXXXX)

# Cleanup on exit
trap "rm -f $temp_file; rm -rf $temp_dir" EXIT

Process Control and Job Scheduling

Signal Handling

# Trap signals
trap "echo 'Script interrupted'; exit 1" SIGINT SIGTERM
trap "echo 'Cleaning up...'; rm -f temp_*" EXIT

# Ignore signals
trap "" SIGQUIT

Background Execution

# Run script in background
./long_script.sh &

# No hangup execution
nohup ./persistent_script.sh > output.log 2>&1 &

# Job control
jobs                    # List background jobs
fg %1                   # Bring job 1 to foreground
bg %2                   # Restart job 2 in background
kill %3                 # Terminate job 3

Process Priority

# Launch with specific priority
nice -n 10 ./low_priority.sh

# Adjust running process
renice +5 -p 12345

Scheduled Execution

# One-time job
echo "./backup.sh" | at 02:00 tomorrow

# Recurring job (cron)
# Edit crontab: crontab -e
# Example: Run daily at 3 AM
0 3 * * * /path/to/daily_task.sh

# Anacron for missed jobs
# Configuration in /etc/anacrontab
7 15 weekly.job /path/to/weekly_task.sh

Shell Functions

Function Definition and Usage

# Function syntax
function process_log {
    local log_file="$1"
    echo "Analyzing $log_file"
    grep "ERROR" "$log_file" | wc -l
}

# Alternative syntax
backup_file() {
    local source="$1"
    local dest="$2"
    cp "$source" "$dest"
    echo "Backed up to $dest"
}

# Function call
error_count=$(process_log "/var/log/app.log")
backup_file "data.txt" "/backup/data.txt"

Variable Scope

global_var="visible everywhere"

function demo_scope {
    local local_var="function only"
    global_var="modified in function"
    echo "Local: $local_var"
}

demo_scope
echo "Global: $global_var"  # Shows modification
echo "Local: $local_var"    # Empty (not accessible)

Function Libraries

# library.sh - Reusable functions
function log_message {
    echo "[$(date)] $1" >> /var/log/custom.log
}

function check_disk_space {
    df -h / | awk 'NR==2 {print $5}' | sed 's/%//'
}

# Source library in scripts
source /path/to/library.sh
# Or: . /path/to/library.sh

log_message "Script started"
usage=$(check_disk_space)
if [ $usage -gt 80 ]; then
    log_message "Warning: Disk usage at ${usage}%"
fi

Text Processing with sed and gawk

sed Stream Editor

# Basic substitution
sed 's/old/new/g' file.txt

# In-place editing with backup
sed -i.bak 's/foo/bar/' file.txt

# Line-specific operation
sed '3s/this/that/' file.txt

# Delete lines
sed '/pattern/d' file.txt

# Multiple commands
sed -e 's/a/b/' -e 's/c/d/' file.txt

# Script file
sed -f script.sed file.txt

# Print only matching lines
sed -n '/error/p' logfile

gawk Programming

# Field processing
gawk '{print $1, $3}' data.txt

# Custom field separator
gawk -F: '{print $1}' /etc/passwd

# Pattern matching
gawk '/failed/ {print $0}' auth.log

# BEGIN and END blocks
gawk 'BEGIN {count=0} /error/ {count++} END {print "Errors:", count}' app.log

# Built-in variables
gawk '{print NR, $0}' file.txt  # Print line numbers

Regular Expressions

Basic Regular Expressions (BRE)

# Anchors
^start    # Beginning of line
end$      # End of line

# Character classes
[0-9]     # Any digit
[a-z]     # Any lowercase letter
[^A-Z]    # Any non-uppercase letter

# Repetition
a*        # Zero or more 'a'
a\{2,4\} # 2 to 4 'a' characters

# Special classes
[[:digit:]]    # Digits
[[:alpha:]]    # Letters
[[:space:]]    # Whitespace

Extended Regular Expressions (ERE)

# Extended features (use with grep -E or egrep)
a+        # One or more 'a'
a?        # Zero or one 'a'
a{2,5}    # 2 to 5 'a' (no backslash needed)

# Alternation
(cat|dog) # Matches "cat" or "dog"

# Grouping
(abc)+    # One or more "abc" sequences

Interactive Scripting

Menu Creation

# Traditional menu
while true; do
    clear
    echo "1. Start service"
    echo "2. Stop service"
    echo "3. Check status"
    echo "4. Exit"
    read -p "Select: " choice
    
    case $choice in
        1) start_service ;;
        2) stop_service ;;
        3) check_status ;;
        4) exit 0 ;;
        *) echo "Invalid option" ;;
    esac
    read -p "Press Enter to continue"
done

# Select menu
PS3="Choose option: "
select opt in Start Stop Status Exit; do
    case $opt in
        Start) start_service ;;
        Stop) stop_service ;;
        Status) check_status ;;
        Exit) break ;;
    esac
done

Dialog Components

# Text-based dialogs
dialog --msgbox "Operation complete" 10 40
dialog --yesno "Proceed?" 8 30
if [ $? -eq 0 ]; then
    echo "User confirmed"
fi

# Input box
dialog --inputbox "Enter filename:" 10 50 2> input.txt
filename=$(cat input.txt)

# Menu
dialog --menu "Select option:" 15 50 4 \
    1 "Option One" \
    2 "Option Two" \
    3 "Option Three" 2> choice.txt

Graphical Dialogs

# KDE environment
kdialog --msgbox "Task completed" --title "Notification"

# GNOME environment
zenity --info --text="Processing finished" --title="Status"
selected_file=$(zenity --file-selection --title="Choose a file")

Tags: bash

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.