meta data for this page
  •  

This is an old revision of the document!


Bash

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

include/source other scripts

Possible test scenario:

  1. call using from another directory full path /home/user/bin/myscripth.sh
  2. add /home/user/bin to PATH and then call from another directory by “myscript.sh”
  3. create symlink to script and call using symlink. Check for relative and absolute symlinks.
  4. it should work also if it is sourced “source” or “.”

The best is to create setup/installer script which hardcode path to one shared script.

Another solutions:

#!/bin/sh
MY_DIR=$(dirname $(readlink -f $0))
$MY_DIR/other_script.sh
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd -P "$( dirname "$SOURCE" )" && pwd )"
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"

`BASH_SOURCE' An array variable whose members are the source filenames where the corresponding shell function names in the `FUNCNAME' array variable are defined. The shell function `${FUNCNAME[$i]}' is defined in the file `${BASH_SOURCE[$i]}' and called from `${BASH_SOURCE[$i+1]}'

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