Last active
December 13, 2025 17:17
-
-
Save VladSavitsky/e01316c231d15634a9d02e30b74d0dc8 to your computer and use it in GitHub Desktop.
Bash Calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Bash Calculator using command_not_found_handle | |
| # Version: 7.5.0 | |
| # Uses = as calculator prefix: =2+2, ="(2+3)*4", =[2+3]*4, ?sqrt(16) | |
| # For division, use space: = 10/3 | |
| # Or quote: ='10/3' | |
| calc_internal() { | |
| local expression="$*" | |
| # If expression is empty, show usage | |
| if [[ -z "$expression" ]]; then | |
| echo "Calculator: =expression" | |
| echo "Examples: =2+2, =\"(2+3)*4\", =\"sqrt(16)\", =.5*2" | |
| echo " =2+2, =\"(2+3)*4\" (for simple expressions)" | |
| return 1 | |
| fi | |
| # Convert brackets to parentheses | |
| expression="${expression//\[/(}" | |
| expression="${expression//\]/)}" | |
| # Add leading zero to decimals starting with . | |
| if [[ "$expression" =~ ^-?\. ]]; then | |
| if [[ "$expression" =~ ^-\. ]]; then | |
| expression="-0.${expression:2}" | |
| else | |
| expression="0.${expression:1}" | |
| fi | |
| fi | |
| # Fix other decimal cases (after operators) | |
| expression=$(echo "$expression" | sed -E ' | |
| s/\(\./(0./g; | |
| s/\+\./+0./g; | |
| s/-\./-0./g; | |
| s/\*\./*0./g; | |
| s/\/\./\/0./g; | |
| ') | |
| # Calculate using bc | |
| local result | |
| result=$(bc -l <<< "scale=3; $expression" 2>&1) | |
| # Check for bc errors | |
| if [[ "$result" =~ ^\(standard_in\) ]] || | |
| [[ "$result" =~ [Ee]rror|[Dd]ivide.*[Zz]ero|[Ss]yntax ]]; then | |
| echo "Math error: Invalid expression" >&2 | |
| return 1 | |
| fi | |
| # Clean result: remove trailing zeros and decimal point | |
| result=$(echo "$result" | sed -E ' | |
| s/\.[0]+$// | |
| s/\.$// | |
| s/^[[:space:]]+// | |
| s/[[:space:]]+$// | |
| ') | |
| [[ -z "$result" ]] && result="0" | |
| [[ "$result" == "-" ]] && result="0" | |
| echo "$result" | |
| } | |
| # This hook allows to use '=expr' (no space) beside '= expr' (with space). | |
| command_not_found_handle() { | |
| # Check if command is "=". | |
| if [[ "$*" =~ ^= ]]; then | |
| # Remove spaces and "=". | |
| expression=$(echo "$@" | sed 's/ //g' | sed 's/=//g'); | |
| calc_internal "$expression" | |
| return $? | |
| fi | |
| echo "bash: $*: command not found" >&2 | |
| return 127 | |
| } | |
| export -f command_not_found_handle 2>/dev/null || true | |
| # Test function | |
| test_bash_calc() { | |
| echo "Testing Bash Calculator - Version 7.5.0" | |
| echo "==================================================" | |
| echo "" | |
| # Store original function | |
| local original_handle=$(declare -f command_not_found_handle) | |
| # Temporarily unset to avoid recursion | |
| unset -f command_not_found_handle 2>/dev/null | |
| echo "Test cases (use space after =):" | |
| echo " =2+2: $(calc_internal '2+2')" | |
| echo " =(2+2): $(calc_internal '(2+2)')" | |
| echo " =(2+3)*4: $(calc_internal '(2+3)*4')" | |
| echo " =[2+3]*4: $(calc_internal '[2+3]*4')" | |
| echo " =10/3: $(calc_internal '10/3')" | |
| echo " =.5*2: $(calc_internal '.5*2')" | |
| echo " =-.5*2: $(calc_internal '-.5*2')" | |
| echo " =sqrt(16): $(calc_internal 'sqrt(16)')" | |
| echo " =2*3*4: $(calc_internal '2*3*4')" | |
| echo " =(5.5+2.3)*2: $(calc_internal '(5.5+2.3)*2')" | |
| echo " =2^8: $(calc_internal '2^8')" | |
| echo " =4*a(1): $(calc_internal '4*a(1)')" | |
| echo " =s(0): $(calc_internal 's(0)')" | |
| echo " =2++3: $(calc_internal '2++3')" | |
| echo " =10/0: $(calc_internal '10/0')" | |
| echo " =: $(calc_internal '')" | |
| echo "" | |
| echo "Simple expressions (no space, no /):" | |
| echo " =2+2: $(calc_internal '2+2')" | |
| echo " =2*3: $(calc_internal '2*3')" | |
| # Restore original function | |
| eval "$original_handle" | |
| export -f command_not_found_handle 2>/dev/null || true | |
| echo "==================================================" | |
| echo "Usage: =expr" | |
| echo "Test complete." | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment