If you like DNray Forum, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...

 

Bash Script for Basic Arithmetic Operations

Started by hvye8gip, Nov 24, 2024, 12:58 AM

Previous topic - Next topic

hvye8gipTopic starter

Developing a Bash Calculator Script: A Technical Brief

Create a Bash script that functions as a command-line calculator, awaiting user input without displaying a prompt. The script should support three primary command types:

The "exit" keyword: Upon encountering this command, the script should output "bye" and terminate execution.
Arithmetic operations: The script should accept three space-separated arguments - the first operand (an integer), an operator (+, -, *, /, %, **), and the second operand (an integer). The script should perform the specified operation and display the result. Subsequently, it should revert to awaiting the next command.
Invalid commands: Any input with an incorrect number of arguments or an unsupported operator should trigger the script to output "error" and exit.
To facilitate testing, you can populate a file with multiple commands and pipe the contents to the script via stdin (e.g.,./script.sh < input.txt). The script should then output all results concurrently.

Example use cases:

Input file contents: 10 + 1 2 ** 10 exit

Expected output: 11 1024 bye

Input file contents: 3 - 5 2/10 exit

Expected output: -2 error

The second command in the latter example is invalid due to the lack of space between the numbers and the operator, resulting in an incorrect argument count.
  •  


linhan

Here's a well-structured and readable code snippet that meets the requirements:

#!/bin/bash

while read -r line; do
  case $line in
    exit) echo "bye"; exit 0;;
    *)
      read -r -a args <<< "$line"
      if [ ${#args[@]} -ne 3 ]; then
        echo "error"
        exit 1
      fi
      case ${args[1]} in
        +) echo $(( ${args[0]} + ${args[2]} ));;
        -) echo $(( ${args[0]} - ${args[2]} ));;
        \*) echo $(( ${args[0]} * ${args[2]} ));;
        /)
          if [ ${args[2]} -eq 0 ]; then
            echo "error"
            exit 1
          fi
          echo $(( ${args[0]} / ${args[2]} ));;
        %)
          if [ ${args[2]} -eq 0 ]; then
            echo "error"
            exit 1
          fi
          echo $(( ${args[0]} % ${args[2]} ));;
        **) echo $(( ${args[0]} ** ${args[2]} ));;
        *) echo "error"; exit 1;;
      esac
      ;;
  esac
done

This script uses a while loop to read input lines, and a case statement to handle the "exit" command. For arithmetic operations, it reads the input line into an array, checks the number of arguments, and performs the specified operation using arithmetic expansion.
  •  

austinpow

I developed a basic calculator, but I'm facing a snag with the exponentiation feature. I'm struggling to implement it correctly.

#!/bin/bash
read -p "Input the first number: " num1
read -p "Input the second number: " num2
read -p "Specify the operation (+, -, *, /, ^): " op

case $op in
  "+") echo "Result: $((num1 + num2))";;
  "-") echo "Result: $((num1 - num2))";;
  "/")
    if [ "$num2" -eq 0 ]; then
      echo "Error: Division by zero is not allowed."
    else
      echo "Result: $((num1 / num2))"
    fi;;
  "*") echo "Result: $((num1 * num2))";;
  "^")
    result=1
    for ((i=0; i<num2; i++)); do
      result=$((result * num1))
    done
    echo "Result: $result";;
  *) echo "Unknown operation";;
esac

# I attempted using 'let' and 'bc' for the exponentiation, but I couldn't get it to function properly.
  •  

Cybives

Lowdown on the code: it's been crafted with Notepad3, stress-tested in Busybox 1.36.0 (shell) and Cygwin 3.1.7 (bash 4.4.12). We're talkin' a bespoke solution, folks!

The code's got a sweet spot for validating expressions, and it's all thanks to the validate_expr function. This bad boy's got a regex pattern that's tighter than a drum, ensuring only legit expressions make the cut.

Here's the code:

#!/bin/bash

# Define a function to validate expressions
validate_expr() {
  [[ "$1" =~ ^[+-]?[0-9]+ ([*/%+-]|\*\*) [+-]?[0-9]+$ ]]
}

# Loop through input until we hit a snag
while read -r a op b; do
  # Check if we're donezo
  if [ "$a" = "bye" ] && [ -z "$op$b" ]; then
    echo "Later, gator!"
    break
  fi

  # Validate the expression, or bust
  if! validate_expr "$a $op $b"; then
    echo "Error, dude!"
    break
  fi

  # We're golden, do the math
  echo "$(( $a $op $b ))"
done
  •  


If you like DNray forum, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...