Triangle in Bash: Complete Solution & Deep Dive Guide

two blue triangle logos

The Complete Guide to Classifying Triangles in Bash Scripting

Learn to classify triangles as equilateral, isosceles, or scalene using Bash scripting. This guide covers essential conditional logic, arithmetic expressions, and the triangle inequality theorem to build a robust and efficient script from scratch, perfect for mastering command-line problem-solving.


Ever found yourself staring at a terminal, needing to perform a seemingly simple logical task, only to get tangled in the cryptic syntax of shell scripting? You're not alone. Many developers, comfortable in high-level languages like Python or Java, find Bash to be an arcane tool used only for basic file operations. But what if you could harness its raw power for quick, effective data validation right from the command line?

Imagine you're processing a stream of data, and part of that data represents geometric shapes. You need a lightweight, dependency-free way to validate if three numbers can even form a triangle before passing them to a more resource-intensive program. This is where Bash shines. The triangle classification problem is the perfect challenge to transform your understanding of Bash from a simple command runner into a powerful scripting language.

In this deep-dive guide, we will walk you through creating a Bash script to determine if a triangle is equilateral, isosceles, or scalene. We'll go beyond just the code, exploring the core mathematical principles, robust error handling, and the fundamental Bash constructs that make it all possible. By the end, you'll not only have a working script but a newfound confidence in using Bash for logical problem-solving.


What is the Triangle Classification Problem?

At its core, the problem is simple: given three side lengths, determine the type of triangle they form. However, a robust solution requires more than just comparing numbers; it demands a solid understanding of geometric rules and how to translate them into code. This task is a classic in programming education because it elegantly tests your grasp of conditional logic and input validation.

The Three Triangle Types

First, let's define the classifications based on the lengths of the sides, let's call them a, b, and c:

  • Equilateral: A triangle where all three sides are of equal length. (a = b = c)
  • Isosceles: A triangle where at least two sides are of equal length. (a = b or b = c or a = c)
  • Scalene: A triangle where all three sides have different lengths.

The Two Golden Rules of Triangle Validity

Before you can classify a triangle, you must first determine if the given side lengths can form a valid triangle at all. Many novice programmers skip this crucial validation step. There are two non-negotiable rules:

  1. All sides must have a positive length. A side length of 0 or a negative number is geometrically impossible. Your script must check that a > 0, b > 0, and c > 0.
  2. The Triangle Inequality Theorem. This theorem states that the sum of the lengths of any two sides of a triangle must be greater than the length of the third side. This ensures the sides can "connect" to form a closed shape.
    • a + b > c
    • a + c > b
    • b + c > a

Only if all these conditions are met can you proceed to classify the triangle. Our script's logic will be built around this two-phase process: first validate, then classify.


Why Use Bash for This Task?

You might be thinking, "Wouldn't Python or JavaScript be easier for this?" And you might be right for complex applications. However, using Bash for this problem offers unique advantages and is an incredibly valuable skill.

  • Ubiquity and Portability: Bash (or a compatible shell like zsh) is available on virtually every Linux, macOS, and Windows (via WSL) system out of the box. A Bash script requires no compiler, no interpreter installation, and no dependency management for simple tasks. It just runs.
  • Lightweight and Fast: For command-line tasks and simple data validation, Bash is extremely fast. It starts instantly and consumes minimal resources, making it ideal for inclusion in larger automation workflows, CI/CD pipelines, or system administration scripts.
  • Mastery of the Command Line: Working through logical problems in Bash forces you to deeply understand how the shell works—argument passing, arithmetic expansion, conditional expressions, and process substitution. This knowledge is transferable and makes you a more effective command-line user.
  • Perfect for Glue Code: Bash is the "glue" of the Unix-like world. It excels at connecting the inputs and outputs of other programs. A script like ours could easily be part of a pipeline, for example: cat data.txt | xargs ./triangle.sh to process lines from a file.

This exercise, from the kodikra learning path, is specifically designed to strengthen these foundational skills, proving that Bash is more than capable of handling sophisticated logic.


How to Build the Triangle Classification Script in Bash

Let's construct our script, triangle.sh, step by step. We will focus on readability, robustness, and modern Bash practices. We'll handle inputs, validate them according to the geometric rules, and finally, classify the triangle.

The Overall Logic Flow

Our script will follow a clear, sequential path. This can be visualized as a decision-making funnel. Invalid inputs are filtered out at each stage, ensuring we only attempt to classify what is mathematically possible.

● Start Script (./triangle.sh a b c)
│
▼
┌───────────────────────────┐
│ Receive Inputs ($1, $2, $3) │
└────────────┬──────────────┘
             │
             ▼
◆ Check Argument Count (is it exactly 3?)
╱                           ╲
Yes (Count = 3)              No (Count != 3)
│                             │
▼                             ▼
┌───────────────────┐      ┌─────────────────┐
│ Validate Side > 0 │      │ Exit with Error │
└────────┬──────────┘      └─────────────────┘
         │
         ▼
◆ Triangle Inequality? (a+b>c, etc.)
╱                           ╲
Yes (Valid Triangle)         No (Invalid)
│                             │
▼                             ▼
┌───────────────────┐      ┌─────────────────┐
│ Classify Triangle │      │ Exit with Error │
└────────┬──────────┘      └─────────────────┘
         │
         ▼
    ● Print Result

Step 1: The Full Script

Here is the complete, well-commented Bash script. We'll break down each part of it in the following sections.


#!/usr/bin/env bash

# triangle.sh - Classify a triangle based on three side lengths.
# Part of the exclusive kodikra.com curriculum.

# --- Main function to encapsulate the logic ---
main() {
    # Assign inputs to descriptive variables for readability
    local side1=$1
    local side2=$2
    local side3=$3
    
    # --- Input Validation Stage ---

    # 1. Check if exactly three arguments are provided.
    if [[ $# -ne 3 ]]; then
        echo "Error: Please provide exactly three side lengths." >&2
        return 1
    fi

    # 2. Use a regex to ensure all inputs are valid numbers (integer or float).
    # This regex allows for numbers like 5, 5.0, 0.5 but not .5 or 5.
    local number_regex='^[0-9]+([.][0-9]+)?$'
    if ! [[ $side1 =~ $number_regex && $side2 =~ $number_regex && $side3 =~ $number_regex ]]; then
        echo "Error: All sides must be valid numbers." >&2
        return 1
    fi

    # 3. Check if all sides are greater than zero.
    # We use `bc` for floating-point comparison.
    # The `scale` variable can be set for precision.
    if ! (( $(echo "$side1 > 0" | bc -l) )) || \
       ! (( $(echo "$side2 > 0" | bc -l) )) || \
       ! (( $(echo "$side3 > 0" | bc -l) )); then
        echo "false"
        return 0
    fi

    # 4. Check the Triangle Inequality Theorem.
    # The sum of any two sides must be greater than the third.
    local sum12_gt_3=$(echo "$side1 + $side2 > $side3" | bc -l)
    local sum13_gt_2=$(echo "$side1 + $side3 > $side2" | bc -l)
    local sum23_gt_1=$(echo "$side2 + $side3 > $side1" | bc -l)

    if ! (( sum12_gt_3 && sum13_gt_2 && sum23_gt_1 )); then
        echo "false"
        return 0
    fi

    # --- Classification Stage ---

    # If we reach this point, we have a valid triangle.
    if (( $(echo "$side1 == $side2" | bc -l) )) && (( $(echo "$side2 == $side3" | bc -l) )); then
        echo "equilateral"
    elif (( $(echo "$side1 == $side2" | bc -l) )) || \
         (( $(echo "$side1 == $side3" | bc -l) )) || \
         (( $(echo "$side2 == $side3" | bc -l) )); then
        echo "isosceles"
    else
        echo "scalene"
    fi
    
    return 0
}

# --- Script Entry Point ---
# Call the main function with all script arguments passed to it.
# The `"$@"` ensures all arguments are passed correctly, even with spaces.
main "$@"

Step 2: Detailed Code Walkthrough

The Shebang and Entry Point


#!/usr/bin/env bash
...
main "$@"

The #!/usr/bin/env bash line is called a "shebang". It tells the operating system to execute this file using the bash interpreter found in the user's environment path. This is more portable than hardcoding #!/bin/bash. The final line, main "$@", is the script's entry point. It calls our main function and passes all the command-line arguments ($@) to it. Quoting "$@" is crucial as it preserves arguments containing spaces.

Variable Assignment and Argument Count


main() {
    local side1=$1
    local side2=$2
    local side3=$3
    
    if [[ $# -ne 3 ]]; then
        echo "Error: Please provide exactly three side lengths." >&2
        return 1
    fi
    ...
}

Inside main, we first assign the positional parameters ($1, $2, $3) to descriptive local variables. This makes the code much easier to read. Our first validation check uses $#, a special variable that holds the number of arguments passed to the script. We use a modern test construct [[ ... ]] to check if the count is not equal (-ne) to 3. If the check fails, we print an error message to standard error (>&2) and exit with a non-zero status code (1), which conventionally signals an error.

Handling Floating-Point Numbers with bc

A major limitation of Bash's built-in arithmetic ((...)) is that it only handles integers. Triangles can certainly have floating-point side lengths (e.g., 1.5, 2.5, 3.5). To handle this robustly, we use the Basic Calculator utility, bc.


# Example of using bc for comparison
if (( $(echo "$side1 > 0" | bc -l) )); then
    # ... code if side1 is greater than 0
fi

Let's break this down:

  • echo "$side1 > 0": This prints the comparison as a string.
  • | bc -l: The pipe | sends this string as input to the bc command. The -l flag loads the standard math library, which is essential for floating-point operations.
  • bc evaluates the expression and outputs 1 for true or 0 for false.
  • $(...): This is command substitution. The shell executes the command inside and replaces it with the output. So, this becomes either 1 or 0.
  • (( ... )): This is Bash's arithmetic context. Inside it, 1 evaluates to true and 0 to false.

This pattern is the standard, most portable way to perform floating-point arithmetic and comparisons in shell scripts.

Validation Logic: Positive Sides and Inequality Theorem


# Check for positive sides
if ! (( $(echo "$side1 > 0" | bc -l) )) || \
   ! (( $(echo "$side2 > 0" | bc -l) )) || \
   ! (( $(echo "$side3 > 0" | bc -l) )); then
    echo "false"
    return 0
fi

# Check triangle inequality
local sum12_gt_3=$(echo "$side1 + $side2 > $side3" | bc -l)
# ... more checks ...
if ! (( sum12_gt_3 && sum13_gt_2 && sum23_gt_1 )); then
    echo "false"
    return 0
fi

Here, we apply the two golden rules. We use our bc pattern to check if any side is not greater than 0. If this condition is met, we print "false" and exit gracefully as per the problem's expected output for invalid triangles. We do the same for the triangle inequality theorem, checking all three combinations. The use of && inside ((...)) acts as a logical AND.

The Classification Logic Flow

Once all validations pass, the script proceeds to the final classification stage. The logic here is a straightforward cascade of checks, prioritized from most specific (equilateral) to least specific (scalene).

    Valid Triangle Input
    │
    ▼
◆ side1 == side2 AND side2 == side3?
╱                           ╲
Yes                          No
│                            │
▼                            ▼
┌─────────────┐       ◆ side1==side2 OR side1==side3 OR side2==side3?
│ Equilateral │      ╱                             ╲
└─────────────┘     Yes                           No
                     │                             │
                     ▼                             ▼
                  ┌───────────┐                 ┌─────────┐
                  │ Isosceles │                 │ Scalene │
                  └───────────┘                 └─────────┘

This logic is implemented with a simple if/elif/else block, again using bc for the comparisons to ensure floating-point numbers are handled correctly.


if (( $(echo "$side1 == $side2" | bc -l) )) && (( $(echo "$side2 == $side3" | bc -l) )); then
    echo "equilateral"
elif (( $(echo "$side1 == $side2" | bc -l) )) || \
     (( $(echo "$side1 == $side3" | bc -l) )) || \
     (( $(echo "$side2 == $side3" | bc -l) )); then
    echo "isosceles"
else
    echo "scalene"
fi

Step 3: How to Run the Script

To use the script, save the code above into a file named triangle.sh. Then, make it executable from your terminal.


# Make the script executable
chmod +x triangle.sh

Now you can run it by providing three side lengths as arguments:


# Test case for an equilateral triangle
$ ./triangle.sh 5 5 5
equilateral

# Test case for an isosceles triangle
$ ./triangle.sh 4 4 6
isosceles

# Test case for a scalene triangle
$ ./triangle.sh 3 4 5
scalene

# Test case for an invalid triangle (violates inequality theorem)
$ ./triangle.sh 1 1 3
false

# Test case for an invalid triangle (side is zero)
$ ./triangle.sh 2 3 0
false

# Test case with floating-point numbers
$ ./triangle.sh 1.5 1.5 1.5
equilateral

# Test case with incorrect number of arguments
$ ./triangle.sh 10 20
Error: Please provide exactly three side lengths.

Alternative Approaches and Considerations

While our script using bc is robust and portable, there are other ways to approach this, each with its own trade-offs.

Using only Bash (Integer Arithmetic)

If you are absolutely certain you will only ever deal with integers, you can simplify the script significantly by using Bash's built-in arithmetic expansion ((...)) and conditional expressions [[...]] with operators like -eq (equal), -gt (greater than), etc.


# Integer-only version (less flexible)
side1=$1
side2=$2
side3=$3

# Integer validation
if (( side1 <= 0 || side2 <= 0 || side3 <= 0 )); then
    echo "false"
    exit 0
fi

# Integer inequality check
if (( side1 + side2 <= side3 || side1 + side3 <= side2 || side2 + side3 <= side1 )); then
    echo "false"
    exit 0
fi

# Integer classification
if (( side1 == side2 && side2 == side3 )); then
    echo "equilateral"
#... and so on

Pros and Cons of Using Bash for This Task

For a balanced perspective, it's important to understand where Bash fits in the landscape of programming languages for a task like this.

Pros of Using Bash Cons of Using Bash
Zero Dependencies: Runs on any standard Unix-like system without installing anything. Awkward Math Syntax: Requires external tools like bc for floating-point math, which can be verbose.
Extremely Lightweight: Instant startup time and very low memory overhead. Limited Data Structures: Lacks complex data structures like objects or classes, making larger programs hard to manage.
Excellent for "Glue": Easily integrates into command-line pipelines and other scripts. Error Proneness: Syntax can be unforgiving (e.g., a missing space in [ ] can break the script).
Teaches Core System Concepts: Forces you to understand processes, I/O redirection, and shell expansion. Less Readable for Complex Logic: As conditional logic grows, Bash can become harder to read than a language like Python.

Frequently Asked Questions (FAQ)

1. What is the Triangle Inequality Theorem again?

The Triangle Inequality Theorem is a fundamental principle in geometry. It states that for any valid triangle, the sum of the lengths of any two sides must be strictly greater than the length of the remaining third side. This ensures the sides can form a closed shape. For sides a, b, and c, all three of these conditions must be true: a + b > c, a + c > b, and b + c > a.

2. Why is bc necessary for Bash arithmetic?

Bash's native arithmetic capabilities, accessed via $((...)), are limited to integers only. It cannot handle decimal points or floating-point numbers. bc (Basic Calculator) is a standard command-line utility that provides a full-featured calculation engine, including support for arbitrary precision arithmetic. By piping calculations to bc, we extend Bash's capabilities to handle real-world numbers.

3. How can I handle non-numeric inputs more gracefully?

Our script includes a regular expression check: [[ $var =~ $regex ]]. This is a robust way to validate the format of the input before attempting calculations. You could expand the regex to be more or less strict, or add another check to specifically catch inputs like "abc" or "12a" and provide a more specific error message.

4. What's the difference between [[ ... ]] and [ ... ] in Bash tests?

[[ ... ]] is a "compound command" and a more modern, powerful version of the original [ ... ] (which is an alias for the test command). Key advantages of [[ ... ]] include built-in support for regular expression matching (=~), logical operators like && and || without needing -a or -o, and less strict rules about word splitting and quoting, making it generally safer and easier to use in modern scripts.

5. Can this script be turned into a reusable function in my .bashrc?

Absolutely! You can copy the entire main function (renaming it to something like triangle_type) into your ~/.bashrc or ~/.zshrc file. This would make the command available in any new terminal session, allowing you to type triangle_type 3 4 5 directly without needing to call the script file.

6. Does the order of the `if/elif/else` checks matter for classification?

Yes, the order is very important for correctness and efficiency. You should always check for the most specific condition first. An equilateral triangle is also technically an isosceles triangle (since "at least two" sides are equal). By checking for equilateral (all three sides equal) first, we correctly classify it. If we checked for isosceles first, an equilateral triangle would be misclassified as merely isosceles.

7. How does Bash handle numbers starting with zero, like 08?

This is a classic Bash "gotcha". In older arithmetic contexts like $((...)), numbers with a leading zero are interpreted as octal (base-8). Since 8 is not a valid octal digit, $((08)) would cause an error. Our script avoids this problem by using bc, which correctly interprets numbers as base-10 regardless of leading zeros.


Conclusion: More Than Just a Triangle

We've successfully built a robust, portable, and efficient Bash script to classify triangles. More importantly, we've explored the fundamental concepts that underpin effective shell scripting: rigorous input validation, handling different data types (integers vs. floats), leveraging external utilities like bc, and structuring logic with clear conditional blocks.

This triangle problem, while simple on the surface, serves as a powerful lesson from the kodikra Bash curriculum. It demonstrates that with the right techniques, Bash is a formidable tool for more than just moving files. It's a capable language for data processing, validation, and automation, essential for any developer, DevOps engineer, or system administrator.

By mastering these patterns, you are well on your way to unlocking the full potential of the command line. Continue exploring, keep scripting, and challenge yourself with more complex problems.

Disclaimer: The code in this article is compatible with Bash version 4.0+ due to the use of the =~ regex operator. The use of bc is dependent on it being installed on the host system (it is standard on most Linux and macOS distributions).


Published by Kodikra — Your trusted Bash learning resource.