Bashism
I use a little library to have a common set of utilities out of the box in my bash scripts, it can be retrieved at https://github.com/lorello/lib.sh
Checking strings
# -z (string length is zero) and -n (string length is not zero) are
# preferred over testing for an empty string
if [[ -z "${my_var}" ]]; then
do_something
fi
Loops
Loop on a rows of a text file
#!/bin/sh
list=/tmp/blacklists/porn/domains
cat $list | while read domains
do
echo $domains
done
Loop on a counter
counter=1
while (( $counter < 10 ))
do
echo $counter
((counter++))
done
Loop on a list of items
modules=(json httpserver jshint)
for module in "${modules[@]}"; do
npm install -g "$module"
done
Looping
for ((i = 0; i < n; i++)); do
...
done
Array loops
names=(
"Aaron Maxwell"
"Wayne Gretzky"
"David Beckham"
"Anderson da Silva"
)
IFS=$'\n\t'
for name in ${names[@]}; do
echo "$name"
done
Loops on files containing spaces
OIFS="$IFS"
IFS=$'\n'
for file in $(find . -type f -name "*.csv")
do
echo "file = '$file'"
done
IFS="$OIFS"
Process CLI options
aaa=''
bbb=''
ccc=''
while [ $# -gt 0 ]
do
case $1 in
-h) print_help ;;
--help) print_help ;;
-a) aaa=$2 ; shift 2 ;;
-b) bbb=$2 ; shift 2 ;;
-c) ccc=$2 ; shift 2 ;;
*) shift 1 ;;
esac
done
Another way
verbose='false'
aflag=''
bflag=''
files=''
while getopts 'abf:v' flag; do
case "${flag}" in
a) aflag='true' ;;
b) bflag='true' ;;
f) files="${OPTARG}" ;;
v) verbose='true' ;;
*) error "Unexpected option ${flag}" ;;
esac
done
A more advanced options is to use [https://github.com/nk412/optparse|optparse]
Bash dates
A simple date useful for filenaming: YYYY-MM-DD
$(date +%F)
A full datetime
$(date +%F-%T)
Builtin bashism instead of external binaries
fqdn='computer1.daveeddy.com'
IFS=. read -r hostname domain tld <<< "$fqdn"
echo "$hostname is in $domain.$tld"
# => "computer1 is in daveeddy.com"
[[ vs [
There is also the long version
[[ a > b ]]
[[ -n $var && -f $var ]] && echo "$var is a file"
[[ $var = img* && ($var = *.png || $var = *.jpg) ]] && \
echo "$var starts with img and ends with .jpg or .png"
[[ $name = a* ]] || echo "name does not start with an 'a': $name"
[[ $(date) =~ ^Fri\ ...\ 13 ]] && echo "It's Friday the 13th!"
Debug
The following code uses the DEBUG trap to inform the user about what command is about to be executed and wait for his confirmation do to so. Put this code in your script, at the location you wish to begin stepping:
trap '(read -p "[$BASH_SOURCE:$LINENO] $BASH_COMMAND?")' DEBUG
Give va value to TRACE to add -x flag to execution:
[[ "$TRACE" ]] && set -x
Some style
meaningful_function_names() { ... }
addition=$((${X} + ${Y}))
substitution="${string/#foo/bar}"
Case formatting
case "${expression}" in
a)
variable="..."
some_command "${variable}" "${other_expr}" ...
;;
absolute)
actions="relative"
another_command "${actions}" "${other_expr}" ...
;;
*)
error "Unexpected expression '${expression}'"
;;
esac