BudiBadu Logo
Samplebadu
Bash Scripting

Learn Bash Scripting by Examples

Bash 5.0+

Bash (Bourne Again SHell) is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. It is the default login shell for most Linux distributions and macOS (until Catalina). Bash is a powerful tool for automating tasks, managing system resources, and stitching together other programs.

This page provides comprehensive code samples to help learners understand Bash scripting from basic commands to advanced automation patterns. Each example includes complete, runnable scripts with line numbers, detailed explanations, and line-by-line breakdowns.

Hello World

Your first Bash script. This sample code demonstrates the shebang line, the echo command, and how to make a script executable.

Comments

Learn how to write single-line and multi-line comments in Bash to document your code with this sample code.

Variables

Understanding how to declare, assign, and access variables in Bash with this sample code. Note the strict syntax rules regarding spaces.

Environment Variables

Learn the difference between local shell variables and exported environment variables with this code example, and how to access system globals.

User Input

How to read input from the user during script execution using the read built-in command, understanding various read options like -p for prompts and -s for silent password input, using -t for timeout to prevent indefinite blocking, reading multiple variables in one command, and implementing robust input validation patterns.

Basic Arithmetic

Performing integer arithmetic in Bash using the $((...)) arithmetic expansion syntax, understanding that Bash only supports integer math without floating-point capability, using arithmetic operators for addition, subtraction, multiplication, division and modulo, implementing increment and decrement operations, and using double parentheses for arithmetic evaluation without expansion.

String Concatenation

Joining strings in Bash is as simple as placing them side-by-side. This sample code shows various concatenation techniques.

String Length

How to get the length of a string variable using the ${#var} parameter expansion syntax, understanding that this counts bytes not characters for multi-byte encodings, using string length in conditional tests for validation, implementing input validation by checking minimum and maximum lengths, and leveraging this for string manipulation operations.

String Replacement

Replace parts of a string using pattern matching syntax ${var/pattern/replacement} with this sample code.

Substring Extraction

Extracting parts of a string using offset and length syntax ${var:offset:length} in this sample code.

Arrays

Working with indexed arrays in Bash: declaration, assignment, and accessing elements with this sample code.

Associative Arrays

Using key-value pairs (dictionaries/maps) in Bash 4.0+ through associative arrays, understanding the mandatory declare -A syntax for proper initialization, accessing values by string keys instead of numeric indices, iterating over keys and values, and implementing lookup tables for configuration management.

Array Iteration

Different ways to loop through array elements including C-style indexed loops and for-each iteration patterns, understanding when to use numeric indices versus direct value iteration, handling arrays with spaces in elements through proper quoting, and choosing the most appropriate loop style for maintainability.

Functions

Defining and calling functions to organize code into reusable blocks, understanding function syntax variations between POSIX and Bash-specific styles, managing variable scope with local declarations, returning values via exit status, and implementing modular script design patterns.

Function Arguments

Passing arguments to functions and accessing them via positional parameters $1, $2, etc., understanding the difference between function arguments and script arguments, using $@ and $* for all arguments, checking argument count with $#, and implementing parameter validation in functions.

Conditionals

Using if-else statements and test operators to implement conditional logic, comparing numbers and strings with different operators, checking file existence and permissions, combining conditions with logical AND and OR, and understanding the importance of proper quoting in test expressions.

Nested Conditionals

Using elif for multiple condition branches and nested if blocks for complex decision trees, implementing multi-level conditionals without deep indentation, choosing between elif chains and case statements for readability, and avoiding common pitfalls in nested conditional logic.

Case Statements

Handling multiple conditions cleanly with case statements as an alternative to long if-elif chains, using pattern matching with wildcards and character classes, implementing default cases with the catch-all pattern, and organizing complex conditional flows with readable case syntax.

Loops

Automating repetitive tasks with for, while, and until loops. Understanding the differences between condition-based loops and iteration-based loops, using brace expansion for numeric ranges, implementing loop control with break and continue statements, and choosing the right loop type for different automation scenarios.

For Loop

Detailed look at the for loop syntax and usage patterns, iterating over explicit lists of values, using brace expansion for numeric and character ranges, processing command output with command substitution, understanding whitespace splitting behavior, and implementing C-style for loops with initialization and increment expressions.

While Loop

Using while loops to repeatedly execute commands as long as a condition evaluates to true, implementing counter-based loops, processing input until a sentinel value is reached, and understanding how while loops differ from for loops in control flow and use cases.

Until Loop

Executing a loop repeatedly until a condition becomes true, understanding the inverse logic compared to while loops, implementing countdown and build-up patterns, and choosing between until and while based on natural condition expression.

Loop Control: Break

Exiting a loop prematurely using the break statement to terminate loop execution when a specific condition is met, implementing early termination patterns for search operations, optimizing loop performance by avoiding unnecessary iterations, and understanding break behavior in nested loops.

Loop Control: Continue

Skipping the rest of the current iteration using the continue statement to immediately jump to the next loop cycle, implementing conditional processing within loops, filtering items during iteration, and avoiding deeply nested conditionals by using continue for guard clauses.

File Operations

Checking file attributes and types using test operators and conditional expressions, determining if paths exist as files or directories, verifying file permissions and ownership, testing file age and size, and implementing robust file validation logic in shell scripts.

Create File

Different ways to create new files including the touch command for empty files, output redirection operators for files with content, and the dd utility for binary files with specific sizes, understanding file creation permissions and umask, implementing atomic file creation patterns, and choosing the appropriate method based on file type and content requirements.

Read File

Reading file contents using various Unix utilities including cat for entire files, head for first lines, tail for last lines and real-time monitoring, understanding line-by-line processing with while read loops for large files, implementing efficient file parsing strategies, and choosing the right tool based on file size and processing needs.

Write File

Overwriting file contents using the > output redirection operator to truncate and write new data, understanding the difference between > for overwrite and >> for append, implementing safe file writing with temporary files and atomic moves, preventing data loss through proper error handling, and using here documents for multi-line content.

Append File

Adding content to the end of a file using the >> append redirection operator without truncating existing data, understanding append-only logging patterns for maintaining audit trails, implementing log rotation strategies, using append mode for incremental backups, and ensuring data integrity during concurrent append operations.

Delete File

Removing files and directories using the rm command with various safety options, understanding the permanent nature of rm and lack of trash/recycle bin, using -i for interactive confirmation, implementing -r for recursive directory deletion, applying -f to force deletion, and following best practices to prevent accidental data loss.

Check File Exists

Verifying if a file exists before performing operations using test operators and conditional expressions, understanding the -f flag for regular files versus -e for any filesystem entity, implementing file validation in scripts to prevent errors, using file existence checks in error handling logic, and combining with other file attribute tests.

Check Directory Exists

Verifying directory existence and creating it if missing using conditional logic with mkdir -p for parent directory creation, understanding the idempotent nature of mkdir -p that prevents errors when directories exist, implementing reliable directory setup in deployment scripts, and ensuring proper permissions for newly created directories.

List Directory

Listing files and directories using the ls command with various formatting options and glob patterns for filtering, understanding ls flags like -l for long format, -a for hidden files, and -h for human-readable sizes, using wildcards and glob patterns to filter listings, and parsing ls output safely in scripts.

Copy Files

Duplicating files and directories using the cp command with various preservation options, understanding the difference between copying single files and recursive directory copies with -r, preserving file attributes like timestamps and permissions with -p, implementing backup strategies, and handling symbolic links properly.

Move Files

Moving and renaming files using the mv command for file operations, understanding the dual purpose of mv for both moving files between directories and renaming files in place, using the -i flag for interactive confirmation to prevent accidental overwrites, implementing atomic rename operations, and handling bulk file moves with loops.

Rename Files

Batch renaming files using loops and parameter expansion to manipulate filenames, including changing extensions, adding prefixes or suffixes, and performing pattern-based transformations across multiple files simultaneously.

File Permissions

Understanding Unix file permission model with read, write, and execute bits for owner, group, and others, along with practical methods for viewing and testing permissions programmatically in shell scripts.

Change Permissions

Modifying file access permissions using chmod command with both symbolic notation for human-readable changes and octal numeric notation for precise control, including common permission patterns for scripts, configuration files, and security-sensitive data.

Change Ownership

Changing file owner and group ownership using chown and chgrp commands, understanding when sudo privileges are required, and applying recursive ownership changes to entire directory trees for system administration tasks.

Process Management

Understanding Process IDs (PID) and managing script execution, including accessing special shell variables for current and parent process IDs, tracking background jobs, and implementing proper process lifecycle management in shell scripts.

List Processes

Viewing and filtering running processes using ps command with various formatting options, understanding BSD versus Unix-style flags, using pgrep for name-based process searches, and extracting specific process information for scripting and system monitoring.

Kill Process

Sending signals to processes to terminate or modify behavior, understanding the difference between SIGTERM for graceful shutdown and SIGKILL for forceful termination, using kill, pkill, and killall commands, and following best practices to avoid data corruption.

Background Processes

Running commands asynchronously using the ampersand operator to launch background jobs, managing multiple parallel tasks with the jobs built-in command, understanding job control with fg and bg, and using wait to synchronize completion of background processes.

Wait Command

Synchronizing parallel execution by pausing script execution until specific background processes or all background jobs complete, capturing exit statuses of background tasks, implementing barrier synchronization patterns, and preventing race conditions in shell scripts.

Piping

Connecting commands together using the pipe operator to create data processing pipelines, understanding how standard output flows to standard input, using xargs to convert stdin to command arguments, leveraging process substitution for advanced redirection, and building complex multi-stage text processing workflows.

Redirection

Controlling input and output streams using redirection operators to manage where commands read from and write to, understanding the distinction between stdout and stderr, overwriting versus appending to files, silencing command output by redirecting to /dev/null, and combining multiple redirection techniques.

Stdin, Stdout, Stderr

Deep dive into file descriptors 0, 1, and 2 representing stdin, stdout, and stderr, understanding how the operating system manages input and output streams, explicitly redirecting to specific file descriptors, creating custom file descriptors for logging and complex I/O patterns, and applying proper stream separation for robust script design.

Here Documents

Passing multi-line input to commands using here documents with the <<EOF syntax, feeding blocks of text into interactive programs, generating configuration files with variable expansion, disabling expansion with quoted delimiters, and using indented here documents with <<- for better code readability.

Here Strings

Passing a single string to stdin using the <<< here string operator for feeding literal strings or variable content to commands, understanding how here strings differ from here documents by providing single-line input, using here strings with commands that read from stdin, avoiding unnecessary echo piping, and implementing clean command input patterns.

Glob Patterns

Matching filenames using standard wildcards and glob patterns including asterisk (*) for any characters, question mark (?) for single characters, and bracket expressions ([]) for character sets, understanding that globs expand before command execution, using glob patterns for file filtering, and distinguishing glob patterns from regular expressions.

Extended Globs

Advanced pattern matching with extended globbing (extglob) enabling complex patterns like +(...) for one or more matches, @(...) for exactly one match, !(...) for negation, *(...) for zero or more, and ?(...) for zero or one, requiring shopt -s extglob to enable, and using extended globs for sophisticated file filtering.

Exit Codes

Understanding exit statuses through the $? special variable that holds the return code of the last executed command, controlling script success and failure with the exit built-in command, using exit codes for error handling and conditional logic, following conventions where 0 means success and non-zero indicates errors, and implementing proper exit code propagation in functions and scripts.

Trap Signals

Handling interrupts and cleanup using the trap command to catch signals like SIGINT, SIGTERM, and EXIT, implementing cleanup functions that execute when scripts are interrupted or terminated, ensuring temporary files are removed, releasing resources properly, and creating robust scripts that handle interruptions gracefully.

Error Handling

Making scripts robust with strict mode settings including set -e to exit on command failure, set -u to treat unset variables as errors, and set -o pipefail to catch failures in pipelines, understanding the trade-offs of strict mode, implementing proper error handling with these flags, and creating production-ready scripts.

Backup Script

A practical script to archive a directory with timestamps for version control and backup purposes, implementing tar compression with gzip for space efficiency, generating unique archive names using date formatting, verifying archive integrity after creation, and organizing archived backups in dedicated directories.

Log Rotation

Rotating logs to prevent disk overflow by implementing log file management strategies, archiving old logs with timestamps for historical retention, compressing rotated logs to save disk space with gzip, deleting outdated archives based on age policies, and automating log rotation through cron jobs or logrotate integration.

Disk Monitor

Alerting when disk usage exceeds a threshold by monitoring filesystem utilization with df command, parsing percentage values for comparison against limits, implementing notification mechanisms through email or logging, automating monitoring with cron schedules, and preventing system failures from disk space exhaustion.

Temp Cleaner

Finding and deleting old files in a directory using the find command with time-based filters, implementing automated cleanup policies with -mtime for modification time, testing with -print before actual deletion with -delete, maintaining system cleanliness by removing temporary files, and implementing safe file deletion patterns with confirmation.

Find Large Files

Locating files larger than a specific size using find command with -size operator, implementing disk space analysis by identifying large files, using human-readable size units like M for megabytes and G for gigabytes, sorting results by size for prioritization, and automating large file cleanup or archival processes.

Daily Backup

Automating the creation of daily archives with precise timestamping for version control and backup management, implementing scheduled archival through cron integration, using date command for generating unique timestamp-based filenames, managing archive retention policies, and ensuring consistent backup snapshots for disaster recovery.

File Sync

Verifying file integrity and synchronizing directories based on content hashes using md5sum or sha256sum for checksum comparison, implementing change detection by comparing hash values, automating file verification processes, detecting corruption or unauthorized modifications, and ensuring data consistency across backup systems.

Folder Watcher

Monitoring a directory for changes using a polling loop to detect new files, modified files, or deletions, implementing basic file watching without inotify dependencies, using find command with timestamps for change detection, automating responses to file system events, and building simple file monitoring solutions.

Duplicate Detector

Finding duplicate files by comparing MD5 hashes to identify identical content regardless of filenames, implementing efficient duplicate detection algorithms using associative arrays, reclaiming disk space by removing redundant copies, automating deduplication processes, and maintaining file system efficiency.

Batch Rename

Mass renaming files using string manipulation and loops for bulk file operations, implementing pattern-based renaming with parameter expansion, changing file extensions across multiple files, adding prefixes or suffixes systematically, and performing complex filename transformations without external tools.

Process Monitor

Continuously checking if a process is running and logging its status by monitoring process IDs with pgrep or ps commands, implementing process health checks for critical services, recording uptime and downtime events, alerting on process failures, and maintaining audit trails of process lifecycle events.

Auto Restart

Detecting service failure and automatically attempting to restart it using systemctl or service commands, implementing self-healing automation for critical services, adding retry logic with exponential backoff, logging restart attempts and outcomes, and preventing infinite restart loops with maximum attempt limits.

CPU Alert

Monitoring system load averages and alerting on high CPU usage by reading from /proc/loadavg or using uptime command, implementing threshold-based alerting for system performance, detecting resource exhaustion before system failure, logging performance metrics, and automating performance monitoring with scheduled checks.

Memory Tracker

Logging available memory to detect leaks or low-memory conditions by parsing /proc/meminfo or using free command, implementing memory monitoring for capacity planning, detecting memory leaks in long-running processes, triggering alerts before out-of-memory situations, and maintaining historical memory usage data.

Service Health

Verifying that a web service is responding to HTTP requests using curl or wget for health checks, implementing application-level monitoring beyond port checks, validating HTTP response codes for service availability, testing web service endpoints automatically, and integrating health checks into deployment pipelines.

Daemon Heartbeat

Simulating a heartbeat mechanism to track service liveness by periodically updating timestamp files or sending heartbeat signals, implementing dead mans switch patterns for monitoring, detecting silent failures when heartbeats stop, building distributed system health checks, and ensuring service responsiveness validation.

Task Scheduler

A lightweight alternative to cron for running sequential tasks without external dependencies, implementing simple task scheduling within scripts, executing commands at specified intervals with sleep, building custom job schedulers, and managing task dependencies without complex cron syntax.

Ping Monitor

Checking network connectivity to multiple hosts using ping commands for network diagnostics, implementing parallel connectivity testing, detecting network outages or routing issues, validating network infrastructure health, and building network monitoring dashboards with bash scripts.

Port Scanner

Testing open ports using /dev/tcp pseudo-device for Bash built-in networking without external tools like nc or telnet, implementing lightweight port scanning for service availability checks, validating network services are listening on expected ports, and building dependency-free network testing scripts.

System Report

Generating a comprehensive HTML system status report combining multiple system metrics into a formatted web dashboard, implementing automated report generation for system monitoring, creating visual status displays with HTML formatting, integrating multiple data sources into unified reports, and building lightweight monitoring dashboards.