Table of Contents

Bash

re-run as other user

if [ $UID == 0 ]; then
    exec su -c "$0" john
fi

Check if command is installed

if ! command -v "${TOOL}" &>/dev/null; then
    echo " Command ${TOOL} not found. Please install it"
    exit 1
fi

and use it inside loop:

for tool in awk bc sed; do
    ....
done

Output

DEBUG() {
    if [ $DEBUG_ENABLE -eq 1 ]; then
    >&2 echo "DBG: $@"
    fi
}

Variables with space

# Treat arguments as parts of one argument
declare DST=$*
 
# Use double colons to pass argument with spaces
nice ionice -c idle btrfs filesystem defragment -v -r -czlib "${DST}"

Quote problematic characters to use in shell invocation:

  QUOTED_VAR="${VAR@Q}"

Default values

${parameter:-word}
    If parameter is unset or null, the expansion of word is substituted. 
    Otherwise, the value of parameter is substituted.
FOO=${VARIABLE:-default}

Or, which will assign to VARIABLE as well:

FOO=${VARIABLE:=default}

reading in loop without subshell

var=0
while read file
do 
  echo $file; var=1
done < <(ls -1 /tmp/)

'read' insid loop

In loop where stdin is redirected the easiest way to use read is:

TTY=`tty`
while read ...
do
  read CTRLC < ${TTY}
done < somedata

concatenate output (subshell)

( command1 ; command2 ; command3 ) | cat
{ command1 ; command2 ; command3 ; } > outfile.txt

leading zeros / octal

To interpret a number as decimal, use 10#n form, eg. 10#09

VAR=077; echo $(($VAR+1))
# 64
 
# specify base method
VAR=077; echo $((10#$VAR+1))
# 78
 
# strip leading zeros method
VAR=077; VAR=${VAR#0}; echo $(($VAR+1))
# 78

double brackets [[ ]]

DBLBRACKETS

Bash double brackets Bash (extended test command) are safer and provides more features but they are not portable (and not sh compatible). Features:

  1. not filename expansion. Strings will be take literally (i.e. “name*”).
  2. operators like || instead of -o
  3. regex matching =~
[[ -e $file_name ]]
[ -e "$file_name" ]

Check if string contains another string

not compatible with sh

if [[ $string == *"word1 word2"* ]] ...
if [[ $string =~ .*word.* ]] ...

Execute command until fail

while command; do :; done