Bash Scripting πŸ‘©πŸ½β€πŸ’»

Bash Scripting πŸ‘©πŸ½β€πŸ’»

Β·

8 min read

Table of Contents

  1. Why did I started learning Bash Scripting?

  2. My learning process

  3. Challenges faced

  4. Interesting discoveries

  5. Examples from my experience

  6. My humble advice and next steps

Why did I started learning Bash Scripting?

I started learning Bash Scripting because I am doing the RoxsRoss DevOps Bootcamp. This is the third post about my journey to become a DevOps Engineer.

You can also check out the first post and the second post.

The next logical step after learning Linux is learning Bash Scripting. But why?πŸ€”

With Bash, you can easily automate repetitive tasks like deploying applications, managing backups, or monitoring systems. This not only saves time but also reduces the risk of errors that can occur with manual processes.

Bash allows you to monitor performance and optimize system usage. You can create scripts to make sure your resources are used efficiently βœ….

Bash is excellent for logging and monitoring. You can set up scripts to collect logs, track system performance, and even trigger alerts based on certain conditions, helping you maintain a reliable system.

Bash scripting empowers DevOps teams to automate workflows, manage environments, and integrate tools smoothly, leading to faster software delivery and better collaboration between development and operations.

My learning process

I must admit that I felt a bit intimidated at first, but I didn't let impostor syndrome take over. Instead, I was very excited about learning BashπŸ‘©πŸ½β€πŸ’».

I found it very interesting, and there were resources provided to learn and practice, such as books (Introduction to Bash Scripting), theory, practical exercises, and challenges.

I started with an introduction to Bash scripting, followed by the fundamentals:

  • Basic Linux commands

  • Permissions and Properties

  • Redirection and Pipes

  • Variables and Basic Operations

  • Control Structures

  • Functions in Bash

  • Process Management in Bash

  • Text Manipulation in Bash

  • Advanced Interaction with the File System in Bash

  • Integration and Automation

I love how the DevOps Bootcamp by Roxs is structured. It felt like it set the foundational knowledge really well.

After finishing the fundamentals, I practiced with the practical cases and exercises provided in the Bootcamp. You can find them on the bootcamp website or my Github.

Regarding the challenges in the Bash section, 2 of the 3 challenges displayed there are already solved in the Linux Challenges section. You can find my solutions for those here πŸ™Œ.

Challenges faced

Since I am currently working as a Frontend Developer, I didn't find it hard to grasp some concepts like Functions in Bash or Control Structures (Loops). Although the syntax was a bit different, the concepts were still similar.

Here's an example of the syntax for a for loop:

#!/bin/bash

# Define a list of items
fruits=("apple" "banana" "cherry")

# Use a for loop to iterate over the list
for fruit in "${fruits[@]}"; do
  echo "I like $fruit"
done

# I like apple
# I like banana
# I like cherry
# I like date

What was a bit tricky for me was Permissions and Properties. Since I hadn't learned about it before (only when I studied it in the Linux section just before this one), it was a new topic, and I don't use it daily.I believe this is more relevant to Sys Admins or DevOps roles than to Developers, at least in my experience. However, I must say I really enjoyed it.

What I found very interesting was that there are two ways to change permissions:

  1. Symbolic

     # Grant read, write, and execute permissions to the user (owner)
     # and read and execute permissions to group and others.
     chmod u+rwx,g+rx,o+rx file.txt
    
    • u+rwx: Adds read, write, and execute permissions to the user (owner).

    • g+rx: Adds read and execute permissions to the group.

    • o+rx: Adds read and execute permissions to others.

  2. Numeric

    In numeric notation, each permission is represented by a number:

    • 4 = read (r)

    • 2 = write (w)

    • 1 = execute (x)

You add these values together to get the desired permissions for each level (user, group, others):

  • 7 = read + write + execute (4 + 2 + 1)

  • 6 = read + write (4 + 2)

  • 5 = read + execute (4 + 1)

  • 4 = read only

    # Set permissions to 755:
    # - User (owner) has read, write, and execute permissions (7)
    # - Group has read and execute permissions (5)
    # - Others have read and execute permissions (5)
    chmod 755 myfile.txt

Both methods can achieve the same result.

Fortunately, each topic includes an exercise section for practice. You can find my solutions in my Bash Exercises GitHub repository.

Interesting discoveries

I found Bash scripting fascinating because it allows you to schedule tasks to run automatically at specific intervals.

* * * * * command_to_execute

Each * represents a different time field:

  1. Minute (0-59)

  2. Hour (0-23)

  3. Day of the month (1-31)

  4. Month (1-12)

  5. Day of the week (0-7, where both 0 and 7 represent Sunday)

For example, here are a couple of cron jobs that run a backup script:

  1. This runs a script at 10:00 AM every Monday.

     0 10 * * 1 /path/to/script.sh
    
  2. This runs a script every Sunday at 5 PM.

     0 17 * * 0 /path/to/script.sh
    
  3. This runs a script at midnight on the first day of each month.

     0 0 1 * * /path/to/script.sh
    

Another thing I found fascinating was the text manipulation capabilities. My favorite command is grep, a powerful tool for searching and manipulating text patterns within files.

Here are some example use cases:

  1. Search for a specific word in a file. For example, let’s say you want to find the word "error" in logfile.txt.

     grep "error" logfile.txt
    

    This will output all lines in logfile.txt that contain the word "error".

  2. Use the -i option to ignore case sensitivity. For example, if you want to find "error" regardless of case:

     grep -i "error" logfile.txt
    

    This will match "Error", "ERROR", "error", etc.

  3. To search for a pattern in all files within a directory and its subdirectories, use the -r option:

     grep -r "error" /path/to/directory
    

    This will look for "error" in all files within /path/to/directory.

Examples from my experience

I would like to share my solution to challenge_01. This challenge was based on a real-world scenario: β€œDesign an Automated Bash Script for Building a Python Application Using the Flask Framework”.

To solve this, I created a bash script called automation.sh that does the following:

  1. Creates a temporary folder named tempdir.

  2. Copies the specified folders and contents into tempdir as outlined in the challenge.

  3. Creates a Dockerfile inside the tempdir using β€œcat << EOF > Dockerfile.” I chose this method because it allows for multi-line text, which was necessary for the Dockerfile.

  4. Builds the image using the Dockerfile.

  5. Runs the image!

Final solution

#!/bin/bash

# Create a temporary folder named tempdir and its subdirectories tempdir/templates and tempdir/static.
mkdir -p tempdir/templates tempdir/static

# Confirm the directory structure has been created
echo "Temporary directories created: tempdir, tempdir/templates, tempdir/static"

# Inside the tempdir folder, copy the static/ folder, templates/ folder, and the application desafio2_app.py.
cp -r static tempdir
cp -r templates tempdir
cp desafio2_app.py tempdir

# Construct a Dockerfile, which will be located inside the temporary folder tempdir.
cat << EOF > tempdir/Dockerfile
    FROM python
    RUN pip install flask
    COPY ./static /home/myapp/static/
    COPY ./templates /home/myapp/templates/
    COPY desafio2_app.py /home/myapp/
    EXPOSE 5050
    CMD ["python3", "/home/myapp/desafio2_app.py"]
EOF

# Build the image
docker build -t desafio2_app ./tempdir

# Run the app
docker run -t -d -p 5050:5050 --name nombreapprunning desafio2_app

You can also find this and other solutions on my πŸ‘‰πŸ‘‰πŸ‘‰πŸ‘‰ Github Repository πŸ‘ˆπŸ‘ˆπŸ‘ˆπŸ‘ˆ.

My humble advice and next steps

My advice is to practice regularly. If you are following the DevOps Bootcamp by Roxs, I strongly recommend completing all the exercises and challenges. These are excellent examples of real-world issues to tackle, and I love that ❀️!

Be patient with yourself and always remember that perseverance leads to success πŸ’ͺ.

Make the most of blogs like Stack Overflow and Medium to see how others solve tasks similar to what you need to do. Learn from those with more experience.

And last but not least, there's a command called man. This is a powerful tool that displays the manual pages for different commands. So, whenever you're unsure about a command, you can check the man page:

For example, viewing the Manual for grep command:

man grep

The output looks like this:

GREP(1)                     General Commands Manual                    GREP(1)

NAME
     grep, egrep, fgrep, rgrep, bzgrep, bzegrep, bzfgrep, zgrep, zegrep,
     zfgrep – file pattern searcher

SYNOPSIS
     grep [-abcdDEFGHhIiJLlMmnOopqRSsUVvwXxZz] [-A num] [-B num] [-C num]
          [-e pattern] [-f file] [--binary-files=value] [--color[=when]]
          [--colour[=when]] [--context=num] [--label] [--line-buffered]
          [--null] [pattern] [file ...]

DESCRIPTION
     The grep utility searches any given input files, selecting lines that
     match one or more patterns.  By default, a pattern matches an input line
     if the regular expression (RE) in the pattern matches the input line
     without its trailing newline.  An empty expression matches every line.
     Each input line that matches at least one of the patterns is written to
     the standard output.
     ....

And that's all about Bash Scripting!

While Bash helped us automate our workflow, Docker is about to transform how we think about development environments entirely. Think of it as taking our Bash superpowers and wrapping them in a portable, shareable container that works exactly the same way everywhere. No more "but it works on my machine" drama!

Next steps... Docker 🐳

See you in the next post, where we'll start our container journey together! πŸš€

Β