My Road to Learn DevOps, Part 2: To Advanced Shell Scripting and Beyond!
Tags: shell, devops
Published: 2023-06-20 19:55:59

In the first part of our journey, we dipped our toes into the world of DevOps, exploring the basics of Linux commands and shell scripting. Now, it's time to dive deeper. We'll explore advanced shell scripting concepts and tackle some practical applications to showcase the expertise sought by those looking for in-depth DevOps knowledge. 

## Advanced Shell Scripting

Shell scripting enables us to automate tasks, manage systems, and much more. Let's go a step further and explore some advanced concepts - functions, command-line arguments, arrays, error handling, and regular expressions.

### Functions in Shell Scripting

A function is a reusable code snippet that performs a specific task. Functions are a fundamental part of clean and efficient code. Here's an example:

```bash
#!/bin/bash
greet() {
    echo "Hello, $1"
}
greet "John Doe"
```

### Command-line Arguments

Scripts can accept input directly from the command line, adding to their flexibility. Here's how to implement this:

```bash
#!/bin/bash
echo "Hello, $1"
```
When running this script with the argument "John Doe" (i.e., `./script.sh "John Doe"`), it will display "Hello, John Doe".

### Arrays in Shell Scripting

Arrays allow you to store multiple values within a single variable, and they are particularly useful when working with large datasets.

```bash
#!/bin/bash
fruits=("Apple" "Banana" "Cherry")
for fruit in "${fruits[@]}"
do
    echo "I like $fruit"
done
```

### Error Handling in Shell Scripting

Handling errors properly makes your scripts more robust and easier to debug. Here's an example:

```bash
#!/bin/bash
set -euo pipefail
invalid_command
echo "This won't print"
```

The `set -euo pipefail` command is a handy tool that tells the shell to exit the script if any command it executes fails.

### Regular Expressions in Shell Scripting

Regular expressions (regex) are powerful tools for pattern matching and data extraction. Here's how you could use them:

```bash
#!/bin/bash
text="The year is 2023"
echo "$text" | grep -oE '[0-9]+'
```
This script will output "2023". The `-o` option tells `grep` to output only the matched segment, and `-E` enables extended regular expression syntax.

## Practical Applications

I've found out that during my learning process, it's not just about knowing the concepts. It's about how you apply them. 

### Automating System Maintenance

With shell scripting, we can automate system maintenance tasks such as log file analysis. Here's an example:

```bash
#!/bin/bash
LOG_FILE="/var/log/syslog"
ERROR_PATTERN="error"
grep -i $ERROR_PATTERN $LOG_FILE > errors.txt
```
This script searches the system log file for entries containing "error" and writes them into a new file. You can schedule this script using a tool like cron to run daily, providing a convenient summary of potential issues.

### Resource Monitoring

We can monitor resources such as CPU and memory usage, ensuring our systems are running efficiently:

```bash
#!/bin/bash
DATE=$(date '+%Y-%m-%d %H:%M:%S')
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1"%"}')
MEMORY_USAGE

=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }')
echo "At $DATE, CPU usage is $CPU_USAGE, Memory usage is $MEMORY_USAGE" >> resource_usage.log
```
This script logs current CPU and memory usage, appending the information to a log file. Like the previous example, you can run this script regularly using cron.

### Backup Management

Ensuring data security through regular backups is critical. With shell scripting, you can automate your backup process. Here's an example of a script that creates a backup of a directory:

```bash
#!/bin/bash
BACKUP_SRC="/path/to/your/directory"
BACKUP_DEST="/path/to/your/backup/location"
DATE=$(date +%Y%m%d)
tar -czf $BACKUP_DEST/backup_$DATE.tar.gz -C $BACKUP_SRC .
```

This script creates a compressed tarball of the specified directory and saves it to the backup location with the current date in the filename.

### Server Health Check

Another common task that we can see on systems is checking the health of servers. Here's a script that performs a simple health check by pinging a server:

```bash
#!/bin/bash
SERVER="your.server.com"
ping -c 1 $SERVER
if [ "$?" -ne 0 ]; then
    echo "$SERVER not reachable"
else
    echo "$SERVER is up"
fi
```

This script pings the server once. If the ping command fails (returning anything other than 0), it indicates the server isn't reachable. Otherwise, it confirms the server is up.

### Checking Disk Space Usage

Monitoring disk space usage is another crucial task that can be automated using shell scripts. Here's an example:

```bash
#!/bin/bash
MAX_USAGE=90
EMAIL="admin@example.com"
for partition in $(df -h | grep "^/" | awk '{print $1}')
do
    USAGE=$(df -h | grep $partition | awk '{ print $5}' | sed 's/%//g')
    if [ $USAGE -gt $MAX_USAGE ]; then
        echo "Running out of disk space in $partition" | mail -s "Disk Space Alert" $EMAIL
    fi
done
```

This script checks the usage of all partitions and sends an email to the system administrator if the usage exceeds 90%.


## Bridging the Gap: Scheduling Jobs in Linux

So, now that we've navigated through the fundamentals of Linux commands and shell scripting, let's take the leap into more intricate territories.

Cron is a time-based job scheduling service in Unix-like operating systems, including Linux. It enables users to schedule jobs (commands or scripts) to run at specific times or on specific days.

##  Time Management with Cron
As we transition from our exploration of advanced shell scripting concepts, it's essential to understand how these scripts can be scheduled to execute automatically. This brings us to Cron—a time-based job scheduling utility in Unix-like operating systems.

Cron allows you to schedule jobs (commands or scripts) to run at specific times or on specified days, which is a fundamental aspect of systems administration and DevOps.

For instance, you might need to perform regular backups, monitor system health, or automate system maintenance—Cron can handle all of these tasks efficiently.

A crontab file is a simple text file that contains a list of commands meant to be run at specified times. These commands (and their related files) are executed by the cron daemon, which launches them in the system's background.

You can open the crontab file for editing using the following command:

```bash
crontab -e
```

A cron job's time schedule is expressed using a syntax that includes five fields:

```bash
*     *     *   *    *        command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of the week (0 - 6) (Sunday=0)
|     |     |   +------- month (1 - 12)
|     |     +--------- day of the month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)
```

The asterisk (*) means every possible value for that field. For example, an asterisk in the hour field would be the same as 'every hour'.

Now, let's look at practical examples of using cron jobs.

### Scheduling a Backup Job

You can use cron to automate the backup script we discussed earlier. For instance, you could schedule it to run every day at midnight like this:

```bash
0 0 * * * /path/to/your/backup_script.sh
```

This tells cron to run your backup script at minute 0 of hour 0 (which is midnight) of every day of the month, every month, and every day of the week.

### Running a Health Check Every Hour

You could run the server health check script we discussed earlier every hour like this:

```bash
0 * * * * /path/to/your/health_check_script.sh
```

This tells cron to run your health check script at minute 0 of every hour of every day of the month, every month, and every day of the week.

### Running a Disk Space Check Twice a Day

The disk space check script could be run twice a day - once at noon and once at midnight - like this:

```bash
0 0,12 * * * /path/to/your/disk_space_check_script.sh
```

This tells cron to run your disk space check script at minute 0 of hour 0 and hour 12 (which is noon) of every day of the month, every month, and every day of the week.

Remember, it's essential to ensure that your scripts have the correct permissions to be executed. Also, make sure that you provide the full path to your script when setting up your cron job. You can save and exit the crontab file after you've added your jobs. The cron daemon will automatically pick up the changes and execute your scripts according to the schedule you've defined.

## The Learning Continues

Deepening our knowledge of DevOps and shell scripting is a journey of continuous learning, it's not just about understanding the tools and languages—it's about practical implementation. Through application, we transform knowledge into expertise. Stay tuned for more! Cheers!