You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下Bash脚本简易计算器多问题排查与修正求助

Bash简易计算器问题排查与修复

问题概述

  • 初始版本无法询问算术操作的第二个操作数,且不支持负数作为操作数;
  • Update 1版本仍存在输出逻辑错误;
  • Update 2版本中非算术操作(如MS、C、MR等)的流程与显示异常。

初始版本脚本

#!/bin/bash

# Display user instructions
echo "Welcome to the Simple Calculator"
echo "Instructions:"
echo "Enter operand: Any digit, MR, MC, Clear (C), Off (X)"
echo "Enter operator: +, -, *, /, MS, M+, MC, Clear (C), Off (X)"
echo "------------------------------------------"

# Initialize variables
result=0
memory=0

while true; do
    # Start an infinite loop to keep the calculator running

    # Prompt for operand
    read -p "Enter operand: " input_operand
    # Use 'read' to get user input for operand and store it in 'input_operand'

    case "$input_operand" in
        [0-9]*) operand="$input_operand";;;
        # If input_operand is a digit, assign it to the 'operand' variable
        "MR") operand="$result";;;
        # If input_operand is "MR", use the previous result as the operand
        "MC") memory=0; echo "0 -> M"; continue;;;
        # If input_operand is "MC", clear the memory and display the message
        "C") result=0; echo "results cleared"; continue;;;
        # If input_operand is "C", clear the result and display the message
        "X") echo "Good bye."; exit 0;;;
        # If input_operand is "X", exit the script with a farewell message
        *) echo "Invalid input. Please re-enter operand."; continue;;;
        # For any other input, display an error message and continue to the next iteration
    esac

    # Prompt for operator
    read -p "Enter operator: " operator
    # Use 'read' to get user input for the operator and store it in 'operator'

    case "$operator" in
        "+") result=$((result + operand));;;
        # If the operator is "+", perform addition
        "-") result=$((result - operand));;;
        # If the operator is "-", perform subtraction
        "*") result=$((result * operand));;;
        # If the operator is "*", perform multiplication
        "/")
            if [ "$operand" -eq 0 ]; then
                echo "Can't divide by zero. Please re-enter divisor."
                continue
            else
                result=$((result / operand))
            fi
            # If the operator is "/", handle division with a check for division by zero
            ;;
        "MS") memory="$result"; echo "$result -> M";;;
        # If the operator is "MS", store the result in memory and display a message
        "M+") memory=$((memory + result));;;
        # If the operator is "M+", add the result to the memory
        "MR") operand="$memory";;;
        # If the operator is "MR", use the value from memory as the operand
        "MC") memory=0; echo "0 -> M";;;
        # If the operator is "MC", clear the memory and display a message
        "C") result=0; echo "results cleared";;;
        # If the operator is "C", clear the result and display a message
        "X") echo "Good bye."; exit 0;;;
        # If the operator is "X", exit the script with a farewell message
        *) echo "Invalid operator. Please re-enter operator."; continue;;;
        # For any other input, display an error message and continue to the next iteration
    esac

    echo "$result $operator $operand = $result"
    # Display the result of the current operation
done

初始版本错误输出

Welcome to the Simple Calculator
Instructions:
Enter operand: Any digit, MR, MC, Clear (C), Off (X)
Enter operator: +, -, *, /, MS, M+, MC, Clear (C), Off (X)
------------------------------------------
Enter operand: 3
Enter operator: *
0 * 3 = 0
Enter operand: 4
Enter operator: +
4 + 4 = 4
Enter operand: 

Update 1修改后脚本

#!/bin/bash
# Display user instructions
echo "Welcome to the Simple Calculator"
echo "Instructions:"
echo "Enter operand: Any digit, MR, MC, Clear (C), Off (X)"
echo "Enter operator: +, -, *, /, MS, M+, MC, Clear (C), Off (X)"
echo "------------------------------------------"

# Initialize variables
result=0
memory=0

# Function to get an operand
get_operand() {
    read -p "Enter operand: " input_operand
    case "$input_operand" in
        [0-9]*) operand="$input_operand";;;
        "MR") operand="$result";;;
        "MC") memory=0; echo "0 -> M";;;
        "C") result=0; echo "results cleared";;;
        "X") echo "Good bye."; exit 0;;;
        *) echo "Invalid input. Please re-enter operand."
           get_operand;;
    esac
}

# Function to get an operator
get_operator() {
    read -p "Enter operator: " operator
    case "$operator" in
        "+"|"-"|"*"|"/") ;;
        "MS") memory="$result"; echo "$result -> M";;;
        "M+") memory=$((memory + result));;;
        "MR") operand="$memory";;;
        "MC") memory=0; echo "0 -> M";;;
        "C") result=0; echo "results cleared";;;
        "X") echo "Good bye."; exit 0;;;
        *) echo "Invalid operator. Please re-enter operator."
           get_operator;;
    esac
}

# Initial operand entry
get_operand

while true; do
    get_operator
    if [ "$operator" == "MS" ] || [ "$operator" == "M+" ]; then
        continue
    fi

    get_operand

    case "$operator" in
        "+") result=$((result + operand));;;
        "-") result=$((result - operand));;;
        "*") result=$((result * operand));;;
        "/")
            if [ "$operand" -eq 0 ]; then
                echo "Can't divide by zero. Please re-enter divisor."
                get_operand
            else
                result=$((result / operand))
            fi
            ;;
    esac

    echo "$result $operator $operand = $result"
done

Update 1错误输出

Welcome to the Simple Calculator
Instructions:
Enter operand: Any digit, MR, MC, Clear (C), Off (X)
Enter operator: +, -, *, /, MS, M+, MC, Clear (C), Off (X)
------------------------------------------
Enter operand: 3
Enter operator: +
Enter operand: 4
4 + 4 = 4
Enter operator:

Update 2修改后脚本

#!/usr/bin/env bash

# Initialize variables
result=0
memory=0

# Function to get an operand
get_operand() {
    local input
    while true; do
        read -p "Enter operand: " input
        case "$input" in
            [0-9]*) echo "$input"; break;;;
            "MR") echo "$result"; break;;;
            "MC") memory=0; echo "0 -> M";;;
            "C") result=0; echo "results cleared";;;
            "X") echo "Good bye."; exit 0;;;
            *) echo "Invalid input. Please re-enter operand."
        esac
    done
}

# Function to get an operator
get_operator() {
    local input
    while true; do
        read -p "Enter operator: " input
        case "$input" in
            "+"|"-"|"*"|"/") echo "$input"; break;;;
            "MS") memory="$result"; echo "$result -> M";;;
            "M+") memory=$((memory + result));;;
            "MR") echo "$memory"; break;;;
            "MC") memory=0; echo "0 -> M";;;
            "C") result=0; echo "results cleared";;;
            "X") echo "Good bye."; exit 0;;;
            *) echo "Invalid operator. Please re-enter operator."
        esac
    done
}

# Initial operand entry
result=$(get_operand)

while true; do
    operator=$(get_operator)

    operand=$(get_operand)

    prev_result="$result"
    case "$operator" in
        "+") result=$((result + operand));;;
        "-") result=$((result - operand));;;
        "*") result=$((result * operand));;;
        "/") 
            if [ "$operand" -eq 0 ]; then
                echo "Can't divide by zero. Please re-enter divisor."
                continue
            fi
            result=$((result / operand))
            ;;
    esac

    echo "$prev_result $operator $operand = $result"
done

Update 2错误输出

Enter operand: 3
Enter operator: +
Enter operand: 4
3 + 4 = 7
Enter operator: -
Enter operand: 12
7 - 12 = -5
Enter operator: MS
Enter operator: *
Enter operand: 3
-5 -5 -> M
* 3 = -5
Enter operator: C
Enter operator: C
Enter operator: MR
Enter operand: 

预期正确输出示例

$ ./calc
[ *** User instructions displayed *** ]
Enter operand: 3
Enter operator: +
Enter operand: 4
3 + 4 = 7
Enter operator: -
Enter operand: 12
7 - 12 = -5
Enter operator: MS
-5 -> M
Enter operator: *
Enter operand: 3
-5 * 3 = -15
Enter operator: C
results cleared
Enter operand: MR
M -> -5
Enter operator: *
Enter operand: MR
M -> -5
-5 * -5 = 25
Enter operator: M+
25 + -5 = 20 -> M
Enter operator: /
Enter operand: 0
Can't divide by zero. Please re-enter divisor.
Enter operand: 0
Can't divide by zero. Please re-enter divisor.
Enter operand: -6
25 / -6 = -4
Enter operator: +
Enter operand: C
results cleared
Enter operand: -9
Enter operator: k
Sorry, k, is not a valid operator. Please re-enter operator.
Enter operator: MC
0 -> M
Enter operator: +
Enter operand: 3
-9 + 3 = -6
Enter operator: X
Good bye.

修复后的完整脚本

#!/usr/bin/env bash

# 显示用户说明
echo "Welcome to the Simple Calculator"
echo "Instructions:"
echo "Enter operand: Any digit (including negative), MR, MC, Clear (C), Off (X)"
echo "Enter operator: +, -, *, /, MS, M+, MC, Clear (C), Off (X)"
echo "------------------------------------------"

# 初始化变量
result=0
memory=0

# 获取操作数的函数
get_operand() {
    local input
    while true; do
        read -p "Enter operand: " input
        case "$input" in
            # 支持正数和负数格式
            -[0-9]*|[0-9]*) echo "$input"; break;;;
            "MR") echo "$memory"; echo "M -> $memory"; break;;;
            "MC") memory=0; echo "0 -> M";;
            "C") result=0; echo "results cleared";;
            "X") echo "Good bye."; exit 0;;
            *) echo "Invalid input. Please re-enter operand."
        esac
    done
}

# 获取运算符的函数
get_operator() {
    local input
    while true; do
        read -p "Enter operator: " input
        case "$input" in
            "+"|"-"|"*"|"/") echo "$input"; break;;;
            "MS") memory="$result"; echo "$result -> M"; break;;
            "M+") 
                local prev_mem=$memory
                memory=$((memory + result))
                echo "$result + $prev_mem = $memory -> M"
                break;;
            "MC") memory=0; echo "0 -> M"; break;;
            "C") result=0; echo "results cleared"; break;;
            "X") echo "Good bye."; exit 0;;
            *) echo "Sorry, $input, is not a valid operator. Please re-enter operator."
        esac
    done
}

# 初始操作数输入
result=$(get_operand)

while true; do
    operator=$(get_operator)

    # 处理非算术运算符,无需后续操作数,直接回到运算符输入
    case "$operator" in
        "MS"|"M+"|"MC"|"C") continue;;
    esac

    # 循环获取有效的数值操作数,跳过MC/C等非数值返回
    while true; do
        operand=$(get_operand)
        if [[ "$operand" =~ ^-?[0-9]+$ ]]; then
            break
        fi
    done

    prev_result="$result"
    case "$operator" in
        "+") result=$((result + operand));;
        "-") result=$((result - operand));;
        "*") result=$((result * operand));;
        "/") 
            if [ "$operand" -eq 0 ]; then
                echo "Can't divide by zero. Please re-enter divisor."
                continue
            fi
            result=$((result / operand))
            ;;
    esac

    echo "$prev_result $operator $operand = $result"
done

关键修复说明

  1. 支持负数操作数:在get_operand的正则匹配中添加-[0-9]*,兼容负数输入。
  2. 修正非算术操作流程:主循环中判断如果是MS/M+/MC/C这类无需操作数的指令,直接跳过获取操作数步骤,避免无效输入请求。
  3. 操作数有效性校验:添加数值格式检查,确保只有合法的正负整数会被用于计算,排除执行MC/C后的空返回值。
  4. 对齐预期输出格式:
    • MR操作时显示M -> 数值的提示
    • M+操作显示完整的内存计算过程
    • 无效运算符提示包含具体错误运算符名称
  5. 修复初始计算逻辑:调整主循环流程,确保算术操作严格遵循「操作数→运算符→操作数→计算输出」的流程。

内容的提问来源于stack exchange,提问作者Ahmed Dildar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:57:02