Linux CLI 67 ๐ง Number bases and conversion
#!/bin/bash
octal_value="32"
decimal=$(( 0$octal_value ))
echo $decimal
hex_value="1A"
decimal=$(( 0x$hex_value ))
echo $decimal
binary_value="11010"
decimal=$(( 2#$binary_value ))
echo $decimal
decimal=26
octal=$(printf "%o\n" $decimal)
echo $octal
hex=$(printf "%x\n" $decimal)
echo $hex
binary=$(echo "obase=2; $decimal" | bc)
echo $binary
Bash arithmetic works in decimal by default, but it can handle octal, hexadecimal, and binary too. Converting between bases is a common task โ file permissions, memory addresses, bitmasks, and color codes all use non-decimal bases at some point.
Key point: Bash’s arithmetic $((...)) can read numbers in any base using prefixes (0 for octal, 0x for hex, base#number for anything). To write numbers in another base, you need printf (for octal and hex) or bc (for binary).
a – Number bases in shell scripts
You can use variables with different bases by prefixing them:
| Prefix | Base | Example |
|---|---|---|
0x | Hexadecimal (16) | 0x1A = 26 |
0 | Octal (8) | 025 = 21 |
0b | Binary (2) | 0b1010 = 10 |
num_hex=0x1A # hexadecimal
num_oct=025 # octal
num_bin=0b1010 # binary
How bash interprets these:
$ echo $(( 0x1A ))
[ 26 ]
$ echo $(( 025 ))
[ 21 ]
$ echo $(( 0b1010 ))
[ 10 ]
But there’s a catch with variables.
The leading-zero problem:
When you store a number in a variable as a string, the prefix is just part of the string. Bash won’t interpret it unless you tell it to.
$ num=025
$ echo $num
[ 025 ]
$ echo $(( num ))
[ 25 ] # โ interpreted as decimal 25, not octal 21
Bash saw 025 and treated it as plain decimal 25. To force octal interpretation, add the 0 prefix inside the arithmetic expression:
$ num=25
$ echo $(( 0$num ))
[ 21 ] # โ
octal 25 = decimal 21
Or store the value without a leading zero and add it back when converting:
$ octal_value="32"
$ echo $(( 0$octal_value ))
[ 26 ] # octal 32 = decimal 26
Hex works similarly:
$ hex_value="1A"
$ echo $(( 0x$hex_value ))
[ 26 ] # hex 1A = decimal 26
The 0x prefix is added inside $(( )), so bash recognizes the value as hexadecimal.
Binary needs a different form:
Binary can’t use a simple prefix inside $(( )) the way octal and hex do. Use the base#number syntax:
$ binary_value="11010"
$ echo $(( 2#$binary_value ))
[ 26 ] # binary 11010 = decimal 26
The general form is base#number, where base is 2โ64:
| Expression | Meaning | Decimal |
|---|---|---|
2#11010 | Binary | 26 |
8#32 | Octal | 26 |
16#1A | Hex | 26 |
10#25 | Decimal | 25 |
36#Z | Base 36 | 35 |
$ echo $(( 2#11010 ))
[ 26 ]
$ echo $(( 8#32 ))
[ 26 ]
$ echo $(( 16#1A ))
[ 26 ]
$ echo $(( 36#Z ))
[ 35 ]
Important gotchas:
- If you try to convert a string like
0x1Gwith$(( 0x$var )), bash throws an error โGisn’t a valid hex digit:
$ var="1G"
$ echo $(( 0x$var ))
[ bash: 0x1G: value too great for base ]
- Hexadecimal is case-insensitive:
1a==1A. - Octal and binary use only digits โ no letters allowed.
- Leading zeros in decimal literals can silently turn them into octal. Always use
10#to force decimal:
$ echo $(( 010 ))
[ 8 ] # โ octal!
$ echo $(( 10#010 ))
[ 10 ] # โ
decimal
This is a classic bug โ 08 and 09 will fail because they aren’t valid octal digits:
$ echo $(( 08 ))
[ bash: 08: value too great for base (error token is "08") ]
$ echo $(( 10#08 ))
[ 8 ]
Rule of thumb: When converting a user-provided or file-read number that might have a leading zero, always prefix with
10#unless you specifically want octal.
b – Base conversions in shell scripts
Conversion goes two ways: from another base into decimal, and from decimal into another base.
Converting from another base to decimal:
Bash’s $((...)) handles this directly with the right prefix:
| From | Syntax | Example | Result |
|---|---|---|---|
| Octal | $(( 0$var )) | $(( 032 )) | 26 |
| Hex | $(( 0x$var )) | $(( 0x1A )) | 26 |
| Binary | $(( 2#$var )) | $(( 2#11010 )) | 26 |
| Any base | $(( base#$var )) | $(( 36#Z )) | 35 |
# Octal to decimal
$ octal_value="32"
$ decimal=$(( 0$octal_value ))
$ echo $decimal
[ 26 ]
# Hexadecimal to decimal
$ hex_value="1A"
$ decimal=$(( 0x$hex_value ))
$ echo $decimal
[ 26 ]
# Binary to decimal
$ binary_value="11010"
$ decimal=$(( 2#$binary_value ))
$ echo $decimal
[ 26 ]
Converting from decimal to another base:
Bash can’t do this directly inside $(( )) โ it always produces decimal output. You need printf or bc.
Decimal to octal โ printf "%o":
$ decimal=26
$ octal=$(printf "%o\n" $decimal)
$ echo $octal
[ 32 ]
%o formats an integer as octal.
Decimal to hexadecimal โ printf "%x":
$ decimal=26
$ hex=$(printf "%x\n" $decimal)
$ echo $hex
[ 1a ]
%x formats as lowercase hex; %X gives uppercase:
$ printf "%x\n" 26
[ 1a ]
$ printf "%X\n" 26
[ 1A ]
Decimal to binary โ bc:
Bash has no built-in way to output binary. Use bc with obase (output base):
$ decimal=26
$ binary=$(echo "obase=2; $decimal" | bc)
$ echo $binary
[ 11010 ]
More printf base specifiers:
| Format | Meaning | Example |
|---|---|---|
%d | Decimal | printf "%d\n" 26 โ 26 |
%o | Octal | printf "%o\n" 26 โ 32 |
%x | Hex (lower) | printf "%x\n" 26 โ 1a |
%X | Hex (upper) | printf "%X\n" 26 โ 1A |
%#o | Octal with 0 prefix | printf "%#o\n" 26 โ 032 |
%#x | Hex with 0x prefix | printf "%#x\n" 26 โ 0x1a |
%#X | Hex with 0X prefix | printf "%#X\n" 26 โ 0X1A |
$ printf "%o\n" 26
[ 32 ]
$ printf "%x\n" 26
[ 1a ]
$ printf "%X\n" 26
[ 1A ]
$ printf "%#o\n" 26
[ 032 ]
$ printf "%#x\n" 26
[ 0x1a ]
Using bc for any base:
bc can output in any base from 2 to 16 (and beyond with some limitations):
# Decimal to binary
$ echo "obase=2; 26" | bc
[ 11010 ]
# Decimal to octal
$ echo "obase=8; 26" | bc
[ 32 ]
# Decimal to hex
$ echo "obase=16; 26" | bc
[ 1A ]
# Convert back: binary to decimal
$ echo "ibase=2; 11010" | bc
[ 26 ]
# Hex to decimal
$ echo "ibase=16; 1A" | bc
[ 26 ]
obase=Nsets the output baseibase=Nsets the input base
โ ๏ธ Warning: With
bc, setibasebeforeobasewhen converting โ onceibasechanges, the number you pass toobaseis interpreted in the new base. For most simple cases you only set one at a time, so it’s fine.
# Convert from hex to binary in one go
$ echo "ibase=16; obase=2; 1A" | bc
[ 11010 ]
# Convert from binary to hex
$ echo "ibase=2; obase=16; 11010" | bc
[ 1A ]
A complete conversion table:
| From | To | Command |
|---|---|---|
| Octal | Decimal | $(( 0$var )) |
| Hex | Decimal | $(( 0x$var )) |
| Binary | Decimal | $(( 2#$var )) |
| Decimal | Octal | printf "%o\n" $dec |
| Decimal | Hex | printf "%x\n" $dec |
| Decimal | Binary | echo "obase=2; $dec" | bc |
| Hex | Binary | echo "ibase=16; obase=2; $hex" | bc |
| Binary | Hex | echo "ibase=2; obase=16; $bin" | bc |
Converting file permissions (the classic use case):
# Octal permission to symbolic
$ perm=755
$ echo "$(printf "%o" $perm)"
[ 755 ]
# Or read as octal and convert to decimal
$ octal="755"
$ decimal=$(( 0$octal ))
$ echo $decimal
[ 493 ]
# Back to octal with leading zero
$ printf "%#o\n" $decimal
[ 0755 ]
Working with colors (hex โ decimal):
# Hex color #FF8800 โ RGB components
$ hex="FF8800"
$ r=$(( 16#${hex:0:2} ))
$ g=$(( 16#${hex:2:2} ))
$ b=$(( 16#${hex:4:2} ))
$ echo "R=$r G=$g B=$b"
[ R=255 G=136 B=0 ]
# Decimal back to hex color
$ printf "#%02X%02X%02X\n" 255 136 0
[ #FF8800 ]
Bitmask operations:
# Set, clear, and test bits
$ flags=0
$ (( flags |= 0x04 )) # set bit 2
$ (( flags |= 0x01 )) # set bit 0
$ echo $flags
[ 5 ]
$ printf "0x%X\n" $flags
[ 0x5 ]
# Test bit 2
$ (( flags & 0x04 )) && echo "bit 2 set"
[ bit 2 set ]
Formatting output with padding:
# Hex with 4 digits, zero-padded
$ printf "%04X\n" 26
[ 001A ]
# Binary with 8 digits
$ printf "%08d\n" $(echo "obase=2; 26" | bc)
[ 00011010 ]
A complete example โ all bases for 26:
#!/bin/bash
decimal=26
echo "Decimal: $decimal"
echo "Octal: $(printf '%o' $decimal)"
echo "Hex: $(printf '%x' $decimal)"
echo "Binary: $(echo "obase=2; $decimal" | bc)"
echo
echo "Hex with prefix: $(printf '%#x' $decimal)"
echo "Octal with prefix: $(printf '%#o' $decimal)"
# Convert back
octal=$(printf '%o' $decimal)
hex=$(printf '%x' $decimal)
binary=$(echo "obase=2; $decimal" | bc)
echo
echo "Verify โ back to decimal:"
echo "From octal $octal: $(( 0$octal ))"
echo "From hex 0x$hex: $(( 0x$hex ))"
echo "From binary $binary: $(( 2#$binary ))"
[ Decimal: 26 ]
[ Octal: 32 ]
[ Hex: 1a ]
[ Binary: 11010 ]
[ ]
[ Hex with prefix: 0x1a ]
[ Octal with prefix: 032 ]
[ ]
[ Verify โ back to decimal: ]
[ From octal 32: 26 ]
[ From hex 0x1a: 26 ]
[ From binary 11010: 26 ]
The full script from the top of the chapter:
#!/bin/bash
octal_value="32"
decimal=$(( 0$octal_value ))
echo $decimal
hex_value="1A"
decimal=$(( 0x$hex_value ))
echo $decimal
binary_value="11010"
decimal=$(( 2#$binary_value ))
echo $decimal
decimal=26
octal=$(printf "%o\n" $decimal)
echo $octal
hex=$(printf "%x\n" $decimal)
echo $hex
binary=$(echo "obase=2; $decimal" | bc)
echo $binary
[ 26 ]
[ 26 ]
[ 26 ]
[ 32 ]
[ 1a ]
[ 11010 ]
Complete Example Session
# ============================================
# PART 1: OCTAL TO DECIMAL
# ============================================
$ octal_value="32"
$ decimal=$(( 0$octal_value ))
$ echo $decimal
[ 26 ]
$ echo $(( 032 ))
[ 26 ]
$ echo $(( 8#32 ))
[ 26 ]
# ============================================
# PART 2: HEX TO DECIMAL
# ============================================
$ hex_value="1A"
$ decimal=$(( 0x$hex_value ))
$ echo $decimal
[ 26 ]
$ echo $(( 0x1A ))
[ 26 ]
$ echo $(( 0x1a ))
[ 26 ] # case-insensitive
$ echo $(( 16#1A ))
[ 26 ]
# ============================================
# PART 3: BINARY TO DECIMAL
# ============================================
$ binary_value="11010"
$ decimal=$(( 2#$binary_value ))
$ echo $decimal
[ 26 ]
$ echo $(( 2#11010 ))
[ 26 ]
# ============================================
# PART 4: DECIMAL TO OCTAL
# ============================================
$ decimal=26
$ octal=$(printf "%o\n" $decimal)
$ echo $octal
[ 32 ]
$ printf "%#o\n" 26
[ 032 ]
# ============================================
# PART 5: DECIMAL TO HEX
# ============================================
$ hex=$(printf "%x\n" $decimal)
$ echo $hex
[ 1a ]
$ printf "%X\n" 26
[ 1A ]
$ printf "%#x\n" 26
[ 0x1a ]
# ============================================
# PART 6: DECIMAL TO BINARY
# ============================================
$ binary=$(echo "obase=2; $decimal" | bc)
$ echo $binary
[ 11010 ]
$ echo "obase=2; 100" | bc
[ 1100100 ]
# ============================================
# PART 7: BINARY TO HEX VIA BC
# ============================================
$ echo "ibase=2; obase=16; 11010" | bc
[ 1A ]
# ============================================
# PART 8: HEX TO BINARY VIA BC
# ============================================
$ echo "ibase=16; obase=2; 1A" | bc
[ 11010 ]
# ============================================
# PART 9: LEADING ZERO PROBLEM
# ============================================
$ num=025
$ echo $(( num ))
[ 25 ] # โ treated as decimal
$ echo $(( 0$num ))
[ 21 ] # โ
forced octal
$ echo $(( 10#025 ))
[ 25 ] # โ
forced decimal
# ============================================
# PART 10: INVALID DIGITS
# ============================================
$ var="1G"
$ echo $(( 0x$var ))
[ bash: 0x1G: value too great for base ]
$ echo $(( 08 ))
[ bash: 08: value too great for base ]
$ echo $(( 10#08 ))
[ 8 ]
# ============================================
# PART 11: BASE#NUMBER SYNTAX
# ============================================
$ echo $(( 2#11010 ))
[ 26 ]
$ echo $(( 8#32 ))
[ 26 ]
$ echo $(( 16#1A ))
[ 26 ]
$ echo $(( 10#25 ))
[ 25 ]
$ echo $(( 36#Z ))
[ 35 ]
# ============================================
# PART 12: FILE PERMISSIONS
# ============================================
$ perm="755"
$ decimal=$(( 0$perm ))
$ echo $decimal
[ 493 ]
$ printf "%o\n" 493
[ 755 ]
$ printf "%#o\n" 493
[ 0755 ]
# ============================================
# PART 13: HEX COLOR TO RGB
# ============================================
$ hex="FF8800"
$ r=$(( 16#${hex:0:2} ))
$ g=$(( 16#${hex:2:2} ))
$ b=$(( 16#${hex:4:2} ))
$ echo "R=$r G=$g B=$b"
[ R=255 G=136 B=0 ]
$ printf "#%02X%02X%02X\n" 255 136 0
[ #FF8800 ]
# ============================================
# PART 14: PADDED OUTPUT
# ============================================
$ printf "%04X\n" 26
[ 001A ]
$ printf "%08d\n" $(echo "obase=2; 26" | bc)
[ 00011010 ]
# ============================================
# PART 15: BITMASKS
# ============================================
$ flags=0
$ (( flags |= 0x04 ))
$ (( flags |= 0x01 ))
$ echo $flags
[ 5 ]
$ printf "0x%X\n" $flags
[ 0x5 ]
$ (( flags & 0x04 )) && echo "bit 2 set"
[ bit 2 set ]
# ============================================
# PART 16: FULL SCRIPT
# ============================================
$ cat > bases.sh << 'EOF'
#!/bin/bash
octal_value="32"
decimal=$(( 0$octal_value ))
echo $decimal
hex_value="1A"
decimal=$(( 0x$hex_value ))
echo $decimal
binary_value="11010"
decimal=$(( 2#$binary_value ))
echo $decimal
decimal=26
octal=$(printf "%o\n" $decimal)
echo $octal
hex=$(printf "%x\n" $decimal)
echo $hex
binary=$(echo "obase=2; $decimal" | bc)
echo $binary
EOF
$ chmod +x bases.sh
$ ./bases.sh
[ 26 ]
[ 26 ]
[ 26 ]
[ 32 ]
[ 1a ]
[ 11010 ]
Quick Reference
Number Prefixes
| Prefix | Base | Example | Decimal |
|---|---|---|---|
0x | Hex | 0x1A | 26 |
0 | Octal | 032 | 26 |
0b | Binary (bash only) | 0b11010 | 26 |
base# | Any base | 2#11010 | 26 |
Base to Decimal
| From | Syntax | Example |
|---|---|---|
| Octal | $(( 0$var )) | $(( 032 )) โ 26 |
| Hex | $(( 0x$var )) | $(( 0x1A )) โ 26 |
| Binary | $(( 2#$var )) | $(( 2#11010 )) โ 26 |
| Any | $(( base#$var )) | $(( 36#Z )) โ 35 |
| Decimal (force) | $(( 10#$var )) | $(( 10#08 )) โ 8 |
Decimal to Other Bases
| To | Command | Example |
|---|---|---|
| Octal | printf "%o\n" $n | printf "%o\n" 26 โ 32 |
| Hex | printf "%x\n" $n | printf "%x\n" 26 โ 1a |
| HEX | printf "%X\n" $n | printf "%X\n" 26 โ 1A |
| Binary | echo "obase=2; $n" | bc | โ 11010 |
printf Format Specifiers
| Format | Meaning | Example |
|---|---|---|
%d | Decimal | 26 |
%o | Octal | 32 |
%x | Hex (lower) | 1a |
%X | Hex (upper) | 1A |
%#o | Octal with 0 | 032 |
%#x | Hex with 0x | 0x1a |
%#X | Hex with 0X | 0X1A |
%04X | Hex, 4 digits, padded | 001A |
bc Conversions
| Command | Meaning |
|---|---|
echo "obase=2; N" | bc | Decimal โ binary |
echo "obase=8; N" | bc | Decimal โ octal |
echo "obase=16; N" | bc | Decimal โ hex |
echo "ibase=2; N" | bc | Binary โ decimal |
echo "ibase=16; N" | bc | Hex โ decimal |
echo "ibase=2; obase=16; N" | bc | Binary โ hex |
Common Gotchas
| Problem | Cause | Fix |
|---|---|---|
025 = 21, not 25 | Leading zero = octal | Use 10#025 |
08 errors | 8 not valid octal digit | Use 10#08 |
0x1G errors | G not valid hex | Validate input |
0b prefix in old bash | Not supported | Use 2# |
Best Practices
โ Do This:
# Add the prefix inside the arithmetic
decimal=$(( 0$octal_value )) # โ
decimal=$(( 0x$hex_value )) # โ
decimal=$(( 2#$binary_value )) # โ
# Force decimal when leading zeros are possible
echo $(( 10#$num )) # โ
# Use printf for octal and hex output
printf "%o\n" $n # โ
printf "%x\n" $n # โ
# Use bc for binary output
echo "obase=2; $n" | bc # โ
# Validate hex input
[[ "$hex" =~ ^[0-9A-Fa-f]+$ ]] || echo "invalid" # โ
# Use %#o and %#x for prefixed output
printf "%#o\n" $n # โ
032
printf "%#x\n" $n # โ
0x1a
โ Don’t Do This:
# Don't forget the 0 prefix for octal
decimal=$(( $octal_value )) # โ treats 32 as decimal
decimal=$(( 0$octal_value )) # โ
# Don't trust leading zeros
num=025
echo $(( num )) # โ 25, not 21
echo $(( 10#$num )) # โ
25 decimal
echo $(( 0$num )) # โ
21 octal
# Don't use 0b in old bash
echo $(( 0b1010 )) # โ ๏ธ bash 4.0+ only
echo $(( 2#1010 )) # โ
works everywhere
# Don't assume bash can output binary
echo $(( binary )) # โ no such thing
echo "obase=2; $n" | bc # โ
# Don't skip validation on user input
hex="$1"
echo $(( 0x$hex )) # โ errors on bad input
[[ "$hex" =~ ^[0-9A-Fa-f]+$ ]] && echo $(( 0x$hex )) # โ
# Don't forget bc's ibase ordering
echo "obase=2; ibase=16; 1A" | bc # โ ๏ธ obase interpreted in base 16
echo "ibase=16; obase=2; 1A" | bc # โ
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Leading zeros | Treated as octal | Use 10# |
08 or 09 | Invalid octal digits | Use 10#08 |
0x with bad hex | Bash error | Validate input |
| No binary output in bash | $(( )) always decimal | Use bc |
0b in old bash | Not supported | Use 2# |
| bc ibase before obase | Wrong base | Set ibase first |
| Case-sensitivity | Hex accepts both | Either case works |
| Extra output from bc | bc prints result + newline | Use $(...) to capture |
Real-World Examples
1. Octal to Decimal
#!/bin/bash
octal_value="32"
decimal=$(( 0$octal_value ))
echo $decimal
[ 26 ]
2. Hex to Decimal
#!/bin/bash
hex_value="1A"
decimal=$(( 0x$hex_value ))
echo $decimal
[ 26 ]
3. Binary to Decimal
#!/bin/bash
binary_value="11010"
decimal=$(( 2#$binary_value ))
echo $decimal
[ 26 ]
4. Decimal to Octal
#!/bin/bash
decimal=26
octal=$(printf "%o\n" $decimal)
echo $octal
[ 32 ]
5. Decimal to Hex
#!/bin/bash
decimal=26
hex=$(printf "%x\n" $decimal)
echo $hex
[ 1a ]
6. Decimal to Binary
#!/bin/bash
decimal=26
binary=$(echo "obase=2; $decimal" | bc)
echo $binary
[ 11010 ]
7. All Bases for One Number
#!/bin/bash
n=255
echo "Dec: $n"
echo "Oct: $(printf '%o' $n)"
echo "Hex: $(printf '%x' $n)"
echo "Bin: $(echo "obase=2; $n" | bc)"
[ Dec: 255 ]
[ Oct: 377 ]
[ Hex: ff ]
[ Bin: 11111111 ]
8. File Permissions
#!/bin/bash
perm="755"
decimal=$(( 0$perm ))
echo "755 octal = $decimal decimal"
echo "Back to octal: $(printf '%o' $decimal)"
[ 755 octal = 493 decimal ]
[ Back to octal: 755 ]
9. Hex Color to RGB
#!/bin/bash
hex="FF8800"
r=$(( 16#${hex:0:2} ))
g=$(( 16#${hex:2:2} ))
b=$(( 16#${hex:4:2} ))
echo "R=$r G=$g B=$b"
[ R=255 G=136 B=0 ]
10. RGB to Hex Color
#!/bin/bash
printf "#%02X%02X%02X\n" 255 136 0
[ #FF8800 ]
11. Force Decimal with Leading Zero
#!/bin/bash
num="025"
echo $(( 10#$num ))
[ 25 ]
12. Safe Hex Conversion
#!/bin/bash
hex="$1"
if [[ "$hex" =~ ^[0-9A-Fa-f]+$ ]]; then
echo $(( 16#$hex ))
else
echo "Invalid hex: $hex" >&2
exit 1
fi
13. Safe Octal Conversion
#!/bin/bash
oct="$1"
if [[ "$oct" =~ ^[0-7]+$ ]]; then
echo $(( 0$oct ))
else
echo "Invalid octal: $oct" >&2
exit 1
fi
14. Padded Hex Output
#!/bin/bash
for n in 1 15 255 4095; do
printf "0x%04X\n" $n
done
[ 0x0001 ]
[ 0x000F ]
[ 0x00FF ]
[ 0x0FFF ]
15. Padded Binary Output
#!/bin/bash
for n in 1 5 10 255; do
bin=$(echo "obase=2; $n" | bc)
printf "%08d\n" "$bin"
done
[ 00000001 ]
[ 00000101 ]
[ 00001010 ]
[ 11111111 ]
16. Bitmask Flags
#!/bin/bash
READ=0x01
WRITE=0x02
EXEC=0x04
flags=0
(( flags |= READ ))
(( flags |= EXEC ))
echo "Flags: $(printf '0x%02X' $flags)"
(( flags & READ )) && echo "read enabled"
(( flags & WRITE )) && echo "write enabled"
(( flags & EXEC )) && echo "exec enabled"
[ Flags: 0x05 ]
[ read enabled ]
[ exec enabled ]
17. Decimal to Any Base via bc
#!/bin/bash
n=255
for base in 2 8 16; do
echo "Base $base: $(echo "obase=$base; $n" | bc)"
done
[ Base 2: 11111111 ]
[ Base 8: 377 ]
[ Base 16: FF ]
18. Any Base to Decimal
#!/bin/bash
echo $(( 2#11010 ))
echo $(( 8#32 ))
echo $(( 16#1A ))
echo $(( 36#Z ))
[ 26 ]
[ 26 ]
[ 26 ]
[ 35 ]
19. IP Address to Integer
#!/bin/bash
ip="192.168.1.1"
IFS=. read -r a b c d <<< "$ip"
n=$(( (a << 24) | (b << 16) | (c << 8) | d ))
echo "$n"
[ 3232235777 ]
printf "%d.%d.%d.%d\n" \
$(( (n >> 24) & 255 )) \
$(( (n >> 16) & 255 )) \
$(( (n >> 8) & 255 )) \
$(( n & 255 ))
[ 192.168.1.1 ]
20. Full Script
#!/bin/bash
octal_value="32"
decimal=$(( 0$octal_value ))
echo $decimal
hex_value="1A"
decimal=$(( 0x$hex_value ))
echo $decimal
binary_value="11010"
decimal=$(( 2#$binary_value ))
echo $decimal
decimal=26
octal=$(printf "%o\n" $decimal)
echo $octal
hex=$(printf "%x\n" $decimal)
echo $hex
binary=$(echo "obase=2; $decimal" | bc)
echo $binary
Visual: Conversion Map
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Base conversion map โ
โ โ
โ โโโโโโโโโโโโ โ
โ โ DECIMAL โ โ
โ โโโโโโฌโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโผโโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โผ โผ โผ โ
โ โโโโโโโโโ โโโโโโโโโ โโโโโโโโโ โ
โ โ OCTAL โ โ HEX โ โBINARY โ โ
โ โโโโโฌโโโโ โโโโโฌโโโโ โโโโโฌโโโโ โ
โ โ โ โ โ
โ โ printf โ printf โ bc โ
โ โ "%o" โ "%x" โ obase=2 โ
โ โ โ โ โ
โ โ โ โ โ
โ $(( 0$var )) $(( 0x$var )) $(( 2#$var )) โ
โ โ โ โ โ
โ โโโโโโโโโโโโโผโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโ โ
โ โ DECIMAL โ โ
โ โโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: Base Prefixes
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Prefix examples โ
โ โ
โ 0x1A โ hex โ 26 โ
โ 032 โ octal โ 26 โ
โ 0b11010 โ binary โ 26 โ
โ 2#11010 โ binary โ 26 โ
โ 8#32 โ octal โ 26 โ
โ 16#1A โ hex โ 26 โ
โ 10#25 โ decimal โ 25 โ
โ 36#Z โ base36 โ 35 โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Task | Command | Example |
|---|---|---|
| Octal โ Decimal | $(( 0$var )) | $(( 032 )) โ 26 |
| Hex โ Decimal | $(( 0x$var )) | $(( 0x1A )) โ 26 |
| Binary โ Decimal | $(( 2#$var )) | $(( 2#11010 )) โ 26 |
| Any base โ Decimal | $(( base#$var )) | $(( 36#Z )) โ 35 |
| Force decimal | $(( 10#$var )) | $(( 10#08 )) โ 8 |
| Decimal โ Octal | printf "%o\n" $n | printf "%o\n" 26 โ 32 |
| Decimal โ Hex | printf "%x\n" $n | printf "%x\n" 26 โ 1a |
| Decimal โ HEX | printf "%X\n" $n | printf "%X\n" 26 โ 1A |
| Decimal โ Binary | echo "obase=2; $n" | bc | โ 11010 |
| Hex with prefix | printf "%#x\n" $n | โ 0x1a |
| Octal with prefix | printf "%#o\n" $n | โ 032 |
| Padded hex | printf "%04X\n" $n | โ 001A |
| Binary โ Hex | echo "ibase=2; obase=16; N" | bc | โ 1A |
| Hex โ Binary | echo "ibase=16; obase=2; N" | bc | โ 11010 |
Key takeaways:
- Bash reads numbers in any base via prefixes:
0x(hex),0(octal),2#(binary),base#(general) - Bash only writes decimal from
$(( ))โ useprintffor octal and hex,bcfor binary - Leading zeros are dangerous โ
025is octal 21, not decimal 25. Use10#to force decimal 08and09fail as octal โ always use10#when input might have leading zeros- Hex is case-insensitive โ
1a==1A - Use
%#oand%#xto include the base prefix inprintfoutput bchandles any base viaibase(input) andobase(output) โ setibasefirst- Validate input before converting โ
0x1Gand08both crash bash arithmetic - Common uses: file permissions (octal), colors (hex), bitmasks (hex/binary), IP addresses (integer)
- Pad output with
printfformat widths โ%04X,%08d
Remember: Bash arithmetic is flexible about input but fixed on output. Use $(( 0x... )), $(( 0... )), and $(( 2#... )) to read values in any base. Use printf for octal and hex output, and bc for binary. Always guard against leading zeros with 10#. And validate user input before feeding it to $(( )) โ one bad digit crashes the script.
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!