Linux CLI 69 🐧 bc in shell scripts
#!/bin/bash
echo "5 + 3" | bc
a=5
b=3
result=$(echo "$a + $b" | bc)
echo "Result: $result"
echo "scale=2; 10 / 3" | bc
echo "sqrt(2)" | bc -l
echo "e(1)" | bc -l
bc <<EOF
scale=4
(5 + 7) * 3
EOF
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
echo "Result: $result"
else
echo "Error: Division by zero"
fi
Bash arithmetic is integer-only. 10 / 3 gives 3, not 3.33. If you need decimals, square roots, or trigonometric functions, bc is the tool. It’s an arbitrary-precision calculator that reads expressions from stdin and writes results to stdout.
Key point: bc is a full calculator language — variables, functions, loops, conditionals. But in shell scripts you’ll use it mostly for floating-point math and precise decimal arithmetic that $(( )) can’t handle.
a – bc introduction in shell scripts
bc reads input from standard input (stdin) and outputs results to standard output (stdout). You can use it within a shell script by piping expressions to it or by using here documents.
Why bc matters:
Basic arithmetic can be done using $((...)) or expr, but it’s limited to integer operations and does not support decimal precision or advanced mathematical functions like square roots. bc is more versatile in such cases.
| Feature | $(( )) | bc |
|---|---|---|
| Integer arithmetic | ✅ | ✅ |
| Floating point | ❌ | ✅ |
| Square roots | ❌ | ✅ |
| Exponentials | ❌ | ✅ |
| Trig functions | ❌ | ✅ (with -l) |
| Precision control | ❌ | ✅ (scale) |
| Arbitrary precision | ❌ | ✅ |
| Speed | Fastest | Slower |
| External process | No | Yes |
In summary, bc is a powerful tool for advanced mathematical operations in shell scripts, especially for:
- Floating-point calculations
- Complex expressions (e.g., square root, exponentials)
- Precise decimal arithmetic using
scale
Basic usage:
# Pipe an expression
$ echo "5 + 3" | bc
[ 8 ]
# Use a here string
$ bc <<< "5 + 3"
[ 8 ]
# Use a here document
$ bc << EOF
5 + 3
EOF
[ 8 ]
# Interactive
$ bc
5 + 3
8
^D
The scale variable:
scale controls how many decimal places bc produces for division and other operations. Default is 0 — integer results only.
$ echo "10 / 3" | bc
[ 3 ]
$ echo "scale=2; 10 / 3" | bc
[ 3.33 ]
$ echo "scale=5; 10 / 3" | bc
[ 3.33333 ]
$ echo "scale=10; 10 / 3" | bc
[ 3.3333333333 ]
You can set scale once at the top of a here document and it applies to all following lines:
$ bc << EOF
scale=4
10 / 3
20 / 3
1 / 7
EOF
[ 3.3333 ]
[ 6.6666 ]
[ .1428 ]
Note:
scaleaffects division and some transcendental functions. Multiplication and addition of integers aren’t affected.
The -l flag — the math library:
bc -l loads the standard math library, which adds:
| Function | Meaning |
|---|---|
s(x) | Sine |
c(x) | Cosine |
a(x) | Arctangent |
l(x) | Natural log |
e(x) | Exponential (e^x) |
sqrt(x) | Square root |
j(n,x) | Bessel function |
It also sets scale to 20 by default:
$ echo "sqrt(2)" | bc -l
[ 1.41421356237309504880 ]
$ echo "scale=4; sqrt(2)" | bc -l
[ 1.4142 ]
$ echo "e(1)" | bc -l
[ 2.71828182845904523536 ]
Interactive vs scripted:
bc can be used interactively (great for quick math) or in scripts (great for calculation). In scripts, always pipe or use a here document — bc doesn’t like being called with a bare expression argument.
# ❌ Doesn't work — bc ignores the argument
$ bc "5 + 3"
# ✅ Correct — pipe or here string
$ echo "5 + 3" | bc
$ bc <<< "5 + 3"
Variables in bc:
bc has its own variables, separate from bash:
$ bc << EOF
a = 5
b = 3
a + b
a * b
EOF
[ 8 ]
[ 15 ]
You can pass bash variables into bc by interpolating them in the string:
$ a=5
$ b=3
$ echo "$a + $b" | bc
[ 8 ]
Important: Use double quotes so bash expands
$aand$bbefore passing tobc. Single quotes would send$a + $bliterally, andbcwould complain about the$symbol.
Comparison and conditional:
bc supports comparisons that return 1 (true) or 0 (false):
$ echo "5 > 3" | bc
[ 1 ]
$ echo "5 < 3" | bc
[ 0 ]
$ echo "5 == 5" | bc
[ 1 ]
These are useful for tests, though in shell scripts you’d usually use (( )) or [[ ]] for integer comparisons. bc shines when the comparison involves floats:
$ echo "3.14 > 3.13" | bc
[ 1 ]
$ if [ "$(echo "3.14 > 3.13" | bc)" -eq 1 ]; then
> echo "3.14 is bigger"
> fi
[ 3.14 is bigger ]
Base conversion with bc:
bc can also convert between bases using ibase and obase:
$ echo "obase=2; 26" | bc
[ 11010 ]
$ echo "ibase=16; 1A" | bc
[ 26 ]
$ echo "ibase=2; obase=16; 11010" | bc
[ 1A ]
b – bc examples in shell scripts
Here are the seven examples from the top of the chapter, explained one by one.
Example 1 — Simple arithmetic:
echo "5 + 3" | bc
[ 8 ]
The simplest form — an expression piped in, the result piped out. bc reads 5 + 3, computes it, and prints 8.
Example 2 — Using variables:
a=5
b=3
result=$(echo "$a + $b" | bc)
echo "Result: $result"
[ Result: 8 ]
Bash variables are expanded into the string before bc sees it. The $(...) captures bc‘s output. Note the double quotes — they let bash expand $a and $b.
Compare with single quotes:
$ a=5
$ b=3
$ echo '$a + $b' | bc
[ (standard_in) 1: syntax error ]
bc doesn’t understand $a — it’s a shell construct, not bc syntax.
Example 3 — Division with two decimal places:
echo "scale=2; 10 / 3" | bc
[ 3.33 ]
Without scale, 10 / 3 gives 3 (integer division). With scale=2, it gives 3.33. Use semicolons to separate multiple statements on one line.
Example 4 — Square root:
echo "sqrt(2)" | bc -l
[ 1.41421356237309504880 ]
-l loads the math library, enabling sqrt(). The default scale with -l is 20, so you get 20 digits of precision. To control it:
$ echo "scale=4; sqrt(2)" | bc -l
[ 1.4142 ]
Example 5 — Exponential:
echo "e(1)" | bc -l
[ 2.71828182845904523536 ]
e(x) computes e^x. e(1) gives Euler’s number (≈ 2.71828). Again, -l is required.
Example 6 — Using here documents:
bc <<EOF
scale=4
(5 + 7) * 3
EOF
[ 36 ]
A here document lets you pass multiple lines to bc. The scale=4 sets precision for the session; (5 + 7) * 3 evaluates to 36. Here documents are the cleanest way to run multi-statement bc sessions.
Example 7 — Error handling:
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
echo "Result: $result"
else
echo "Error: Division by zero"
fi
[ Error: Division by zero ]
bc doesn’t exit non-zero on division by zero — it prints an error message to stderr and returns 0. So to detect the error, you check bc‘s output and stderr:
$ echo "10 / 0" | bc
[ Runtime error (func=(main), adr=4): Divide by zero ]
$ echo $?
[ 0 ]
The 2>/dev/null hides the error from the terminal. The if checks whether result is non-empty — but that’s not quite right, because bc prints nothing on success in some cases. A better approach:
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null) && [ -n "$result" ]; then
echo "Result: $result"
else
echo "Error"
fi
Or check stderr explicitly:
if ! output=$(echo "scale=2; 10 / 0" | bc 2>&1 >/dev/null) ; then
echo "Error: $output"
fi
Actually the cleanest way is to validate the input before passing it to bc:
divisor=0
if [ "$divisor" -eq 0 ]; then
echo "Error: division by zero" >&2
exit 1
fi
echo "scale=2; 10 / $divisor" | bc
Tip:
bcis forgiving — it prints errors to stderr but still returns 0. Don’t rely on$?alone; check the output or the stderr.
More bc examples:
# Compute average
total=175
count=4
avg=$(echo "scale=2; $total / $count" | bc)
echo "Average: $avg"
[ Average: 43.75 ]
# Circle area
radius=5
pi=$(echo "scale=10; 4*a(1)" | bc -l) # atan(1)*4 = pi
area=$(echo "scale=2; $pi * $radius * $radius" | bc)
echo "Area: $area"
[ Area: 78.53 ]
# Compound interest
principal=1000
rate=0.05
years=10
amount=$(echo "scale=2; $principal * e($rate * $years)" | bc -l)
echo "Amount: $amount"
# Percentage
part=25
whole=200
pct=$(echo "scale=1; $part * 100 / $whole" | bc)
echo "$pct%"
[ 12.5% ]
# Comparison
a=3.14
b=3.13
if [ "$(echo "$a > $b" | bc)" -eq 1 ]; then
echo "$a > $b"
fi
[ 3.14 > 3.13 ]
# Round to nearest integer
x=3.7
echo "($x + 0.5) / 1" | bc
[ 4 ]
# Absolute value
x=-5
echo "if ($x < 0) -$x else $x" | bc
[ 5 ]
# Min/max
a=10
b=20
echo "if ($a < $b) $a else $b" | bc # min
[ 10 ]
echo "if ($a > $b) $a else $b" | bc # max
[ 20 ]
# Power
echo "2^10" | bc
[ 1024 ]
# Modulus (works on floats too!)
echo "scale=2; 10.5 % 3" | bc
[ 1.50 ]
Multi-statement here documents:
bc << EOF
scale=4
# Rectangle
w = 5.5
h = 3.2
area = w * h
perimeter = 2 * (w + h)
"Area: " ; area
"Perimeter: " ; perimeter
EOF
[ Area: 17.6000 ]
[ Perimeter: 17.4000 ]
Strings in double quotes are printed literally, and ; separates statements.
Using bc with a script file:
For complex calculations, put the bc code in a file and invoke it:
$ cat > calc.bc << 'EOF'
scale=4
define f(x) {
return x * x + 2 * x + 1
}
f(3)
EOF
$ bc -l calc.bc
[ 16.0000 ]
bc supports user-defined functions with define. This is rarely needed in shell scripts, but it’s there if you need it.
c – bc tips in shell scripts
Tip 1 — Quoting expressions:
Always use double quotes when passing bash variable expressions to bc — otherwise the shell won’t expand the variables, or it will expand them in unexpected ways.
# ❌ Single quotes — bc sees literal $a
$ echo '$a + $b' | bc
[ syntax error ]
# ✅ Double quotes — bash expands $a and $b
$ echo "$a + $b" | bc
[ 8 ]
# ⚠️ Unquoted — word splitting can break things
$ echo $a + $b | bc
[ 8 ] # works here, but fragile
For complex expressions with special characters, quote the whole thing:
$ echo "scale=2; $a * ($b + 1)" | bc
Tip 2 — Setting scale:
For precise decimal output, always set scale explicitly. The default is 0, which truncates everything after the decimal point.
# ❌ Default scale — integer result
$ echo "10 / 3" | bc
[ 3 ]
# ✅ Explicit scale
$ echo "scale=2; 10 / 3" | bc
[ 3.33 ]
# ✅ With -l, default scale is 20
$ echo "10 / 3" | bc -l
[ 3.33333333333333333333 ]
If you want a specific precision, put it first:
$ echo "scale=4; 10 / 3" | bc
[ 3.3333 ]
Tip 3 — Error handling:
bc prints errors to stderr but returns exit code 0. Don’t rely on $? alone. Use one of these approaches:
# Approach 1: Capture stderr and check
if ! err=$(echo "10 / 0" | bc -l 2>&1 >/dev/null); then
echo "Error: $err" >&2
fi
# Approach 2: Validate input first
if [ "$divisor" -eq 0 ]; then
echo "Error: division by zero" >&2
exit 1
fi
echo "scale=2; $numerator / $divisor" | bc
# Approach 3: Check output isn't empty or an error string
result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null)
if [ -z "$result" ] || [[ "$result" == *error* ]]; then
echo "Calculation failed"
fi
The cleanest approach in most scripts is input validation — check before you call bc.
Tip 4 — Use -l for the math library:
When you need sqrt(), e(), l() (log), or trig functions, pass -l. Without it, bc doesn’t know them.
$ echo "sqrt(2)" | bc
[ syntax error ]
$ echo "sqrt(2)" | bc -l
[ 1.41421356237309504880 ]
Tip 5 — Here documents for complex sessions:
When you have multiple calculations or want to set scale once, use a here document:
bc << EOF
scale=4
a = 10
b = 3
a / b
a * b
a - b
EOF
This avoids repeating scale= on every line.
Tip 6 — Trailing newline:
bc outputs a newline after each result. When using $(...), the trailing newline is stripped automatically:
$ result=$(echo "5 + 3" | bc)
$ echo "[$result]"
[ [8] ] # no trailing newline inside
Tip 7 — Avoid bc for integer arithmetic:
For integers, use $(( )) — it’s faster and doesn’t spawn a process:
# ❌ Slower — spawns bc
$ result=$(echo "$a + $b" | bc)
# ✅ Faster — built-in
$ result=$((a + b))
Use bc only when you need floats or math functions.
Tip 8 — Watch out for locale:
bc uses . as the decimal separator regardless of locale. If your script expects a comma (e.g., 3,14), you’ll need to convert.
$ LC_ALL=de_DE.UTF-8 echo "3.14 + 1" | bc
[ 4.14 ] # still uses .
Putting the tips together:
#!/bin/bash
# Validate input first
numerator=10
divisor=0
if [ "$divisor" -eq 0 ]; then
echo "Error: division by zero" >&2
exit 1
fi
# Use double quotes and explicit scale
result=$(echo "scale=2; $numerator / $divisor" | bc 2>/dev/null)
# Verify we got something
if [ -z "$result" ]; then
echo "Calculation failed" >&2
exit 1
fi
echo "Result: $result"
A complete error-handling pattern:
#!/bin/bash
calc() {
local expr="$1"
local result
local error
error=$(echo "$expr" | bc -l 2>&1 >/dev/null)
result=$(echo "$expr" | bc -l 2>/dev/null)
if [ -n "$error" ]; then
echo "Error: $error" >&2
return 1
fi
echo "$result"
}
if result=$(calc "scale=2; 10 / 3"); then
echo "Result: $result"
fi
By integrating
bcinto your scripts, you can handle a wide range of numerical problems that go beyond the standard shell arithmetic capabilities.
Complete Example Session
# ============================================
# PART 1: BASIC
# ============================================
$ echo "5 + 3" | bc
[ 8 ]
$ bc <<< "5 + 3"
[ 8 ]
# ============================================
# PART 2: VARIABLES
# ============================================
$ a=5
$ b=3
$ result=$(echo "$a + $b" | bc)
$ echo "Result: $result"
[ Result: 8 ]
# ============================================
# PART 3: SCALE
# ============================================
$ echo "10 / 3" | bc
[ 3 ]
$ echo "scale=2; 10 / 3" | bc
[ 3.33 ]
$ echo "scale=5; 10 / 3" | bc
[ 3.33333 ]
# ============================================
# PART 4: -l MATH LIBRARY
# ============================================
$ echo "sqrt(2)" | bc -l
[ 1.41421356237309504880 ]
$ echo "scale=4; sqrt(2)" | bc -l
[ 1.4142 ]
$ echo "e(1)" | bc -l
[ 2.71828182845904523536 ]
$ echo "scale=10; 4*a(1)" | bc -l # pi
[ 3.1415926535 ]
# ============================================
# PART 5: HERE DOCUMENT
# ============================================
$ bc << EOF
> scale=4
> (5 + 7) * 3
> 10 / 3
> EOF
[ 36 ]
[ 3.3333 ]
# ============================================
# PART 6: ERROR HANDLING
# ============================================
$ echo "10 / 0" | bc
[ Runtime error (func=(main), adr=4): Divide by zero ]
$ echo $?
[ 0 ]
$ if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
> echo "Result: $result"
> else
> echo "Error: Division by zero"
> fi
[ Error: Division by zero ]
# ============================================
# PART 7: AVERAGE
# ============================================
$ total=175
$ count=4
$ avg=$(echo "scale=2; $total / $count" | bc)
$ echo "Average: $avg"
[ Average: 43.75 ]
# ============================================
# PART 8: PERCENTAGE
# ============================================
$ part=25
$ whole=200
$ pct=$(echo "scale=1; $part * 100 / $whole" | bc)
$ echo "$pct%"
[ 12.5% ]
# ============================================
# PART 9: FLOAT COMPARISON
# ============================================
$ echo "3.14 > 3.13" | bc
[ 1 ]
$ if [ "$(echo "3.14 > 3.13" | bc)" -eq 1 ]; then
> echo "yes"
> fi
[ yes ]
# ============================================
# PART 10: ROUNDING
# ============================================
$ x=3.7
$ echo "($x + 0.5) / 1" | bc
[ 4 ]
$ x=3.4
$ echo "($x + 0.5) / 1" | bc
[ 3 ]
# ============================================
# PART 11: MIN/MAX
# ============================================
$ a=10
$ b=20
$ echo "if ($a < $b) $a else $b" | bc
[ 10 ]
$ echo "if ($a > $b) $a else $b" | bc
[ 20 ]
# ============================================
# PART 12: FLOATS IN MODULUS
# ============================================
$ echo "scale=2; 10.5 % 3" | bc
[ 1.50 ]
# ============================================
# PART 13: POWER
# ============================================
$ echo "2^10" | bc
[ 1024 ]
# ============================================
# PART 14: CIRCLE AREA
# ============================================
$ radius=5
$ pi=$(echo "scale=10; 4*a(1)" | bc -l)
$ area=$(echo "scale=2; $pi * $radius * $radius" | bc)
$ echo "Area: $area"
[ Area: 78.53 ]
# ============================================
# PART 15: ABSOLUTE VALUE
# ============================================
$ x=-5
$ echo "if ($x < 0) -$x else $x" | bc
[ 5 ]
# ============================================
# PART 16: BASE CONVERSION
# ============================================
$ echo "obase=2; 26" | bc
[ 11010 ]
$ echo "ibase=16; 1A" | bc
[ 26 ]
# ============================================
# PART 17: FULL SCRIPT
# ============================================
$ cat > bc-examples.sh << 'EOF'
#!/bin/bash
echo "5 + 3" | bc
a=5
b=3
result=$(echo "$a + $b" | bc)
echo "Result: $result"
echo "scale=2; 10 / 3" | bc
echo "sqrt(2)" | bc -l
echo "e(1)" | bc -l
bc <<EOF2
scale=4
(5 + 7) * 3
EOF2
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
echo "Result: $result"
else
echo "Error: Division by zero"
fi
EOF
$ chmod +x bc-examples.sh
$ ./bc-examples.sh
[ 8 ]
[ Result: 8 ]
[ 3.33 ]
[ 1.41421356237309504880 ]
[ 2.71828182845904523536 ]
[ 36 ]
[ Error: Division by zero ]
Quick Reference
bc Basics
| Command | Meaning |
|---|---|
echo "EXPR" | bc | Evaluate expression |
bc <<< "EXPR" | Here string |
bc << EOF ... EOF | Here document |
bc -l | Load math library |
bc file.bc | Run a bc script file |
bc Variables
| Variable | Meaning | Default |
|---|---|---|
scale | Decimal places | 0 |
ibase | Input base | 10 |
obase | Output base | 10 |
last | Last result | — |
bc Operators
| Operator | Meaning |
|---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulus |
^ | Power |
++ / -- | Increment / decrement |
+= -= *= /= | Compound assignment |
== != < <= > >= | Comparison |
&& || ! | Logical |
bc Math Library (-l)
| Function | Meaning |
|---|---|
s(x) | Sine |
c(x) | Cosine |
a(x) | Arctangent |
l(x) | Natural log |
e(x) | e^x |
sqrt(x) | Square root |
j(n,x) | Bessel |
bc vs $(( ))
| Feature | $(( )) | bc |
|---|---|---|
| Integers | ✅ | ✅ |
| Floats | ❌ | ✅ |
| scale control | ❌ | ✅ |
| sqrt, e, log | ❌ | ✅ (with -l) |
| Arbitrary precision | ❌ | ✅ |
| Speed | Fastest | Slower |
| External process | No | Yes |
Common Patterns
| Pattern | Example |
|---|---|
| Simple math | echo "5 + 3" | bc |
| With variables | echo "$a + $b" | bc |
| With scale | echo "scale=2; $a / $b" | bc |
| Square root | echo "sqrt($x)" | bc -l |
| Multi-line | bc << EOF ... EOF |
| Capture | result=$(echo "..." | bc) |
| Float compare | echo "$a > $b" | bc |
Best Practices
✅ Do This:
# Quote expressions with double quotes
echo "$a + $b" | bc # ✅
# Always set scale for division
echo "scale=2; $a / $b" | bc # ✅
# Use -l for sqrt, e, log
echo "sqrt(2)" | bc -l # ✅
# Use here documents for multiple statements
bc << EOF
scale=4
$a / $b
$a * $b
EOF # ✅
# Validate divisors before dividing
[ "$b" -eq 0 ] && { echo "div by zero"; exit 1; }
echo "scale=2; $a / $b" | bc # ✅
# Use $(( )) for integers
result=$((a + b)) # ✅
# Capture output with $()
result=$(echo "scale=2; $a / $b" | bc) # ✅
# Use here strings for short expressions
result=$(bc <<< "scale=2; $a / $b") # ✅
❌ Don’t Do This:
# Don't use single quotes with variables
echo '$a + $b' | bc # ❌ syntax error
# Don't forget scale for division
echo "10 / 3" | bc # ❌ gives 3
# Don't use bc for integers
result=$(echo "$a + $b" | bc) # ⚠️ use $((a+b))
# Don't expect non-zero exit on error
echo "10 / 0" | bc; echo $? # ⚠️ prints 0
# Don't forget -l for math functions
echo "sqrt(2)" | bc # ❌ syntax error
# Don't call bc with a bare argument
bc "5 + 3" # ❌ ignores the argument
# Don't use bc for base64 or hex strings
echo "obase=16; FF" | bc # ⚠️ FF isn't decimal
# Don't assume locale decimal separator
echo "3,14 + 1" | bc # ❌ syntax error
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Single quotes | Vars not expanded | Use double quotes |
No scale | Integer division | Set scale=N |
No -l | Math functions fail | Add -l |
| Division by zero | Silent error | Validate input |
| bc exit code 0 | Error not caught | Check stderr/output |
bc "expr" | Argument ignored | Pipe or here string |
| Trailing newline | Extra in output | $() strips it |
| Locale comma | 3,14 errors | bc uses . always |
Real-World Examples
1. Simple Arithmetic
#!/bin/bash
echo "5 + 3" | bc
[ 8 ]
2. Using Variables
#!/bin/bash
a=5
b=3
result=$(echo "$a + $b" | bc)
echo "Result: $result"
[ Result: 8 ]
3. Division with Decimals
#!/bin/bash
echo "scale=2; 10 / 3" | bc
[ 3.33 ]
4. Square Root
#!/bin/bash
echo "sqrt(2)" | bc -l
[ 1.41421356237309504880 ]
5. Exponential
#!/bin/bash
echo "e(1)" | bc -l
[ 2.71828182845904523536 ]
6. Here Document
#!/bin/bash
bc << EOF
scale=4
(5 + 7) * 3
EOF
[ 36 ]
7. Error Handling
#!/bin/bash
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
echo "Result: $result"
else
echo "Error: Division by zero"
fi
[ Error: Division by zero ]
8. Average of Numbers
#!/bin/bash
total=175
count=4
avg=$(echo "scale=2; $total / $count" | bc)
echo "Average: $avg"
[ Average: 43.75 ]
9. Percentage
#!/bin/bash
part=25
whole=200
pct=$(echo "scale=1; $part * 100 / $whole" | bc)
echo "$pct%"
[ 12.5% ]
10. Circle Area
#!/bin/bash
radius=5
pi=$(echo "scale=10; 4*a(1)" | bc -l)
area=$(echo "scale=2; $pi * $radius * $radius" | bc)
echo "Area: $area"
[ Area: 78.53 ]
11. Compound Interest
#!/bin/bash
p=1000
r=0.05
t=10
amount=$(echo "scale=2; $p * e($r * $t)" | bc -l)
echo "Amount: $amount"
[ Amount: 1648.72 ]
12. Float Comparison
#!/bin/bash
a=3.14
b=3.13
if [ "$(echo "$a > $b" | bc)" -eq 1 ]; then
echo "$a > $b"
fi
[ 3.14 > 3.13 ]
13. Round to Integer
#!/bin/bash
x=3.7
result=$(echo "($x + 0.5) / 1" | bc)
echo "$result"
[ 4 ]
14. Absolute Value
#!/bin/bash
x=-5
echo "if ($x < 0) -$x else $x" | bc
[ 5 ]
15. Min and Max
#!/bin/bash
a=10
b=20
echo "Min: $(echo "if ($a < $b) $a else $b" | bc)"
echo "Max: $(echo "if ($a > $b) $a else $b" | bc)"
[ Min: 10 ]
[ Max: 20 ]
16. Power
#!/bin/bash
echo "2^10" | bc
[ 1024 ]
17. Float Modulus
#!/bin/bash
echo "scale=2; 10.5 % 3" | bc
[ 1.50 ]
18. Sum a List
#!/bin/bash
sum=0
for n in 1.5 2.5 3.0 4.25; do
sum=$(echo "$sum + $n" | bc)
done
echo "Sum: $sum"
[ Sum: 11.25 ]
19. Interactive Calculator
#!/bin/bash
while true; do
read -p "calc> " expr
[ "$expr" = "quit" ] && break
echo "$expr" | bc -l
done
20. Full Example Script
#!/bin/bash
# Simple arithmetic
echo "5 + 3" | bc
# Variables
a=5
b=3
result=$(echo "$a + $b" | bc)
echo "Result: $result"
# Division with scale
echo "scale=2; 10 / 3" | bc
# Square root
echo "sqrt(2)" | bc -l
# Exponential
echo "e(1)" | bc -l
# Here document
bc <<EOF
scale=4
(5 + 7) * 3
EOF
# Error handling
if result=$(echo "scale=2; 10 / 0" | bc 2>/dev/null); then
echo "Result: $result"
else
echo "Error: Division by zero"
fi
Visual: bc vs $(( ))
┌──────────────────────────────────────────────┐
│ $(( )) — integer only │
│ │
│ $ echo $((10 / 3)) │
│ [ 3 ] │
│ │
│ Fast, built-in │
│ No decimals, no sqrt, no e() │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ bc — arbitrary precision │
│ │
│ $ echo "scale=2; 10 / 3" | bc │
│ [ 3.33 ] │
│ │
│ $ echo "sqrt(2)" | bc -l │
│ [ 1.41421356237309504880 ] │
│ │
│ Slower, spawns a process │
│ Decimals, sqrt, e, log, trig │
│ │
└──────────────────────────────────────────────┘
Visual: bc Pipeline
┌──────────────────────────────────────────────┐
│ bc pipeline │
│ │
│ echo "scale=2; 10/3" │
│ │ │
│ │ (stdin) │
│ ▼ │
│ ┌──────────────────┐ │
│ │ bc │ ← reads expression │
│ │ │ ← evaluates │
│ └────────┬─────────┘ │
│ │ │
│ │ (stdout) │
│ ▼ │
│ 3.33 │
│ │
│ Capture with $() │
│ result=$(echo "..." | bc) │
│ │
└──────────────────────────────────────────────┘
Summary
| Command | Purpose | Example |
|---|---|---|
echo "E" | bc | Evaluate expression | echo "5 + 3" | bc |
bc <<< "E" | Here string | bc <<< "5 + 3" |
bc << EOF ... EOF | Here document | Multi-line |
bc -l | Math library | echo "sqrt(2)" | bc -l |
scale=N | Decimal places | echo "scale=2; 10/3" | bc |
a=5; a+3 | Variables in bc | echo "a=5; a+3" | bc |
$a + $b | Bash vars | echo "$a + $b" | bc |
sqrt(x) | Square root | bc -l |
e(x) | Exponential | bc -l |
l(x) | Natural log | bc -l |
a(x) | Arctangent | bc -l |
s(x) / c(x) | Sine / cosine | bc -l |
ibase=N | Input base | echo "ibase=16; 1A" | bc |
obase=N | Output base | echo "obase=2; 26" | bc |
Key takeaways:
bcis for floating-point and precise decimal arithmetic — the things$(( ))can’t doecho "EXPR" \| bcis the primary pattern;bc <<< "EXPR"and here documents also work- Always set
scalefor decimal output — default is 0 (integer only) - Use
-lfor the math library —sqrt(),e(),l(), trig functions - Quote with double quotes when using bash variables —
"$a + $b", not'$a + $b' bcexits 0 even on errors — validate input or check stderr- Here documents are best for multi-line
bcsessions - Use
$(( ))for integers —bcis slower because it spawns a process bcsupports variables, functions, loops, and conditionals — it’s a full language- Common uses: averages, percentages, circle geometry, compound interest, float comparisons
ibaseandobaseletbcconvert between number bases as a bonus
Remember: When $(( )) runs out of precision, reach for bc. Pipe an expression in, capture the result with $(...). Set scale for decimals. Use -l for math functions. Quote with double quotes. And validate your input — bc won’t tell you it failed. Master bc, and your shell scripts can do real math.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!