Bash Index : B - The 'B' Bash commands : description, flags and examples

base64

Usage :

Encode / decode strings (or files) into / from base64 format.
Once base64-encoded, some file types have recognizable "signatures" (i.e. the base64 strings start with the same characters) :
PNG files
iVBORw0KGgoAAAANSUhEUgAAA
JPG files
/9j/4AAQSkZJRgABAQ

This is what I've seen when looking at files I encoded. Maybe this reflects exceptions rather than generic situations (for instance, most if not all the files I've base64-encoded were previously edited with Gimp).

Flags :

Flag Usage
(none) encode parameter into base64 format
-d base64EncodedString
--decode base64EncodedString
decode base64EncodedString
-w n
--wrap=n
wrap encoded lines after n characters (defaults to 76).
Use 0 to disable line wrapping (i.e. output a giant single line)

Example :

Encode data into base64 :

  • echo -n 'HelloWorld' | base64
  • Or :
    1. base64 -
    2. HelloWorld If you press now, it'll be appended to the string to encode.
    3. CTRL-d-d
    4. The encoded string will be displayed right after the input string : SGVsbG9Xb3JsZA==

Decode a base64 string :

  • echo 'Ik5ldmVyIHRydXN0IGEgY29tcHV0ZXIgeW91IGNhbid0IHRocm93IG91dCBhIHdpbmRvdyIgLSBTdGV2ZSBXb3puaWFr' | base64 -d
  • echo 'Ik5ldmVyIHRydXN0IGEgY29tcHV0ZXIgeW91IGNhbid0IHRocm93IG91dCBhIHdpbmRvdyIgLSBTdGV2ZSBXb3puaWFr' | openssl enc -d -base64

basename

basename file
return the file name without its path
basename file string
same as above + remove string from the end of the file name. This can be used to remove a known file extension.

bc

Usage :

bc is a calculator that can be used either
There's a common misconception about the -l flag and its necessity in floating point divisions :
  • -l is actually not necessary if you set the scale yourself
  • if you use neither -l nor scale in a division, you'll only get the integer part of the result. The displayed result is NOT :
    • a round() of the result
    • a modulo ...
echo '1/2' | bc; echo '1/2' | bc -l; echo 'scale=2; 1/2' | bc
0			integer part only
.50000000000000000000	20 decimals, as expected 
.50			only 2 decimals, as specified
for i in {8..16}; do echo -n "$i / 3 = "; echo $i/3 | bc; done
8 / 3 = 2
9 / 3 = 3
10 / 3 = 3
11 / 3 = 3
12 / 3 = 4
13 / 3 = 4
14 / 3 = 4
15 / 3 = 5
16 / 3 = 5

Flags :

Flag Usage
-l --mathlib
  • Preload a standard math library (i.e. define some maths functions)
  • and sets the scale to 20
(source)

Standard functions

Function Usage
scale=n set the number of digits after the decimal point to n
echo 'scale=3; 1+1; 1/1' | bc
2
1.000
defaults to 0.

Example :

Some basic examples :

echo '1+1' | bc
2
echo '331507551852/1024/1024/1024' | bc
308

How to round float numbers into integers (source, see also) ?

echo '(3.141592654+0.5)/1' | bc
3
echo '(2.71828+0.5)/1' | bc
3
printf %0.f 3.141592654
3
printf %0.f 3.1 3.5 3.9
344
number=3.333; multiplier=3; echo $(printf %0.f $(echo "$number*$multiplier" | bc))
10
Trying to round numbers with printf :

for i in 0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5; do printf "i : %s, round(i,0) : %.0f\n" "$i" "$i"; done | column -t
i  :  0.5,  round(i,0)  :  0		can't explain this
i  :  1.5,  round(i,0)  :  2		can't explain this
i  :  2.5,  round(i,0)  :  2
i  :  3.5,  round(i,0)  :  4
i  :  4.5,  round(i,0)  :  4
i  :  5.5,  round(i,0)  :  6
i  :  6.5,  round(i,0)  :  6
i  :  7.5,  round(i,0)  :  8
i  :  8.5,  round(i,0)  :  8
i  :  9.5,  round(i,0)  :  10
for i in 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1; do printf "i : %s, round(i,1) : %.1f, round(i,0) : %.0f\n" "$i" "$i" "$i"; done | column -t
i  :  0,    round(i,1)  :  0.0,  round(i,0)  :  0
i  :  0.1,  round(i,1)  :  0.1,  round(i,0)  :  0
i  :  0.2,  round(i,1)  :  0.2,  round(i,0)  :  0
i  :  0.3,  round(i,1)  :  0.3,  round(i,0)  :  0
i  :  0.4,  round(i,1)  :  0.4,  round(i,0)  :  0
i  :  0.5,  round(i,1)  :  0.5,  round(i,0)  :  0	not rounded to 1 
i  :  0.6,  round(i,1)  :  0.6,  round(i,0)  :  1
i  :  0.7,  round(i,1)  :  0.7,  round(i,0)  :  1
i  :  0.8,  round(i,1)  :  0.8,  round(i,0)  :  1
i  :  0.9,  round(i,1)  :  0.9,  round(i,0)  :  1
i  :  1,    round(i,1)  :  1.0,  round(i,0)  :  1
for i in 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1; do simple=$(echo "$i/1" | bc); rounded=$(echo "($i+0.5)/1" | /usr/bin/bc); echo "$i $simple $rounded"; done | column -t
0    0                       0
0.1  .10000000000000000000   0
0.2  .20000000000000000000   0
0.3  .30000000000000000000   0
0.4  .40000000000000000000   0
0.5  .50000000000000000000   1	now rounded to 1 
0.6  .60000000000000000000   1
0.7  .70000000000000000000   1
0.8  .80000000000000000000   1
0.9  .90000000000000000000   1
1    1.00000000000000000000  1
var=2.5; echo $var | awk '{print int($1+0.5)}' 3
for i in {1000..1005}; do a=$(echo "$i/2" | /usr/bin/bc); b=$(echo "scale=1; $i/2" | /usr/bin/bc); c=$(echo "scale=1; (($i/2)+0.5)/1" | /usr/bin/bc); echo -e "$i/2=\t$a\t$b\t$c"; done
1000/2= 500     500.0   500.5
1001/2= 500     500.5   501.0
1002/2= 501     501.0   501.5
1003/2= 501     501.5   502.0
1004/2= 502     502.0   502.5
1005/2= 502     502.5   503.0
==> so far, I've found no "pure-bc" means to round to integer

How to convert numbers between HEX, BIN and DEC (source) ?

To do so, use the ibase (input base) and obase (output base) bc options :

echo 'ibase=16; FF' | bc Hexadecimal letters must be written uppercase.
255
echo 'obase=16; 255 | bc
FF
echo 'ibase=10; obase=2; 73' | bc
1001001

break

Usage :

break n exits from the smallest enclosing for, while, or until loop, or from the nth enclosing loop, if n is specified (defaults to 1).

Example :

Basic example : interrupting a single for loop :

#!/usr/bin/env bash

for i in {1..2}; do
	echo $i
	break
	echo 'this will never be executed'
done
displays :
1

2 nested for loops :

#!/usr/bin/env bash

for i in {1..2}; do
	for j in {a..b}; do
		echo $i$j
		break
		echo 'this will never be executed'
	done
done
displays :
1a
2a

2 nested for loops and break 2 :

#!/usr/bin/env bash

for i in {1..2}; do
	for j in {a..b}; do
		echo $i$j
		break 2
		echo 'this will never be executed'
	done
done
displays :
1a

bzip2

Compress data need a little more details...
You definitely should have a look at pbzip2 :
  1. apt-get install pbzip2
  2. Create aliases :
    alias bzip2='pbzip2'
    alias bunzip2='pbzip2 -d'