Bash secret powers

Bash scripting has evolved a lot in the last ten years.

I get used to relay on bash for all normal “data domination” tasks (like file system refactorings, database extraction and reporting and so on) and switching to python/ruby/perl when the complexity gets bigger. I didn’t imagine bash is even more powerful :) This article by Robert Muth so you new nice tricks: I  add here some other like mapfile and stress the most important one.

Update 2016 Last but not least,if you do now know about bash history, this link will teach you a huge set of tricks
Updated 2019 Bash Bible will further extend the topic.

 

Fail early

First of all, start every script with

#!/bin/bash
set -o nounset
set -o errexit

So your script will alt if an error occur.

The magic $@ is beter then $*

The $@ is to be preferred instead of $* when you must pass parameters to other scripts because it sees arguments as separate word. I want to know it ten years ago!

Using $@ you can do wrapper script which can pass around input to other stuff.

No more temp files with <()

The <() operator is very nice to provide the output of a command like a file, so you avoid creating temp file names (no more $$ magic!)

# download and diff two webpages
diff <(wget -O - url1) <(wget -O - url2)

Reporting needs?

A nice feature is mapfile because it read lines from the standard input into an indexed array variable. You can also avoid the loop:

mapfile -t filecontent <"$logfile"
#....
printf "%s\n" "${filecontent[@]}"

It also support reading from a file descriptor and also a callback function too.
Piping inside mapfile  seems not to work in some case (I think by bash is too old and buggy), so the following  way

< <(find . ) mapfile -t -n 3 ;echo "${MAPFILE[@]}"
mapfile -t < <(printf '%s\n' {1..5000} )

is the suggested one by me: it also helps to remember the useful <() operator.
As you see is also possible to use prinf to make  loop ranges (line 2).

Collapsing Functions

A collapsing function is a function whose behavior changes depending upon the circumstances under which it’s run. Function collapsing is useful when you find yourself repeatedly checking a variable whose value never change.

#!/bin/bash

[[ $1 = -v || $1 = --verbose ]] && verbose=1

chatter() {
if [[ $verbose ]]; then
chatter() {
echo "$@"
}
chatter "$@"
else
chatter() {
:
}
fi
}

The trick is is to redefine the funtcion upon first run.
If not abused, the trick is quite clean to use.

Last but not least: blogging!

Blogging rocks, you know ya?. So this wonderful bashblog script at https://github.com/cfenollosa/bashblog  will give you a sneak peek on how to write a well structured application…in bash!