8.5. Lab: Modular Scripting#

8.5.1. Exercise 6: Backup Manager with Functions#

Create a comprehensive backup solution using modular functions.

File: lib_backup.sh

Create functions:

  • backup_init: Initialize backup directory, validate permissions

  • backup_validate_source: Check that source exists and is readable

  • backup_create: Create tar.gz backup with timestamp

  • backup_list: List available backups

  • backup_restore: Restore from a backup with confirmation

  • backup_cleanup: Delete old backups (keep only N most recent)

Main Script: backup.sh

Usage:

$ ./backup.sh create /home/user/documents    # Create backup
$ ./backup.sh list                           # List backups
$ ./backup.sh restore documents_20240119     # Restore specific backup
$ ./backup.sh cleanup 5                      # Keep only 5 most recent

Requirements:

  • All functions use local variables

  • Clear error messages to stderr

  • Appropriate return codes for different failures

  • Confirmation prompts for destructive operations

  • Backup directory: /backups (configurable)

  • Naming format: source_YYYYMMDD_HHMMSS.tar.gz

Hints:

  • Use timestamp functions for naming

  • Use tar czf for compression

  • Validate prerequisites before operations

  • Use read prompts for confirmations (Exercise 4, Chapter 7)

8.5.2. Exercise 5: System Check Script#

Create a comprehensive system checking library.

File: lib_syscheck.sh

Create functions:

  • check_disk_space: Warn if usage > 80%

  • check_memory_usage: Warn if usage > 90%

  • check_running_services: List critical services status (ssh, httpd, etc.)

  • check_network: Verify internet connectivity

  • generate_report: Call all checks and produce a summary

Example Output:

=== System Health Report ===
Disk Usage: 65% (OK)
Memory Usage: 42% (OK)
Network: OK (google.com reachable)
Services:
  sshd: running ✓
  httpd: running ✓
  mysql: running ✓

Overall Status: HEALTHY

Hints:

  • Use df for disk space

  • Use free for memory

  • Use systemctl status for services

  • Use ping for network check (with timeout)

  • Format output with colors or symbols for readability

8.5.3. Exercise 4: Configuration File Parser#

Create functions to manage and validate configuration.

Requirements:

  • Function config_load: Load config from file (format: key=value)

  • Function config_get: Get value for a key, return error if not found

  • Function config_set: Update or add a key-value pair

  • Function config_validate: Ensure required keys exist

  • Create a config file and script that uses these functions

  • Use associative arrays if bash 4+, otherwise use namespaced variables

Example Config File (app.conf):

app_name=MyApp
app_version=1.0.0
app_port=8080
db_host=localhost
db_port=5432

Example Usage:

$ source lib_config.sh
$ config_load app.conf
$ config_get app_port   # Output: 8080
$ config_set app_port 9000

Hints:

  • Parse config using while IFS='=' read loop

  • Validate required keys in config_validate

  • Handle missing/malformed config gracefully

8.5.4. Exercise 3: File Statistics Function#

Create a function that provides comprehensive file statistics.

Requirements:

  • Function file_stats: Takes filename as argument

  • Returns: file size (bytes), line count, word count, last modified time

  • Return status 0 on success, 1 if file not found, 2 if not readable

  • Output format: size:lines:words:modified

  • Handle errors gracefully with messages to stderr

Example Run:

$ ./file_analyzer.sh /etc/passwd
"/etc/passwd" stats:
Size: 2156 bytes
Lines: 42
Words: 1847
Modified: 2024-01-15 14:23:45

Hints:

  • Use stat to get file size and modification time

  • Use wc to get line and word counts

  • Check file existence and readability

  • Return appropriate codes for different error conditions

8.5.5. Exercise 2: String Utility Library#

Create a reusable library of string functions.

File: lib_string.sh

Create the following functions:

  • string_length: Return length of a string

  • string_upper: Convert string to uppercase

  • string_lower: Convert string to lowercase

  • string_reverse: Reverse a string

  • string_is_empty: Check if string is empty (return 0/1)

  • string_contains: Check if one string contains another

Example Usage:

source lib_string.sh

word="Hello"
string_length "$word"     # Output: 5
string_upper "$word"      # Output: HELLO
string_reverse "$word"    # Output: olleH

Hints:

  • Use ${#variable} for string length

  • Use tr for case conversion

  • Use rev for reversing (or loop with parameter expansion)

  • Use [[ $string =~ pattern ]] for substring checking

8.5.6. Exercise 1: Temperature Converter#

Create functions to convert between temperature scales.

Requirements:

  • Function celsius_to_fahrenheit: Takes Celsius as argument, returns Fahrenheit

  • Function fahrenheit_to_celsius: Takes Fahrenheit as argument, returns Celsius

  • Function celsius_to_kelvin: Takes Celsius as argument, returns Kelvin

  • Main script that reads a temperature and scale, converts to all other scales

  • Use local variables in all functions

  • Handle invalid input with appropriate return codes

Example Run:

$ ./temp_converter.sh 0 C
0°C = 32°F, 273.15K

Hints:

  • Formulas: F = C × 9/5 + 32, K = C + 273.15

  • Use bash arithmetic with decimals carefully (consider using awk for decimal math)

  • Validate input before processing