meta data for this page
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
include/source other scripts
Possible test scenario:
- call using from another directory full path /home/user/bin/myscripth.sh
- add /home/user/bin to PATH and then call from another directory by “myscript.sh”
- create symlink to script and call using symlink. Check for relative and absolute symlinks.
- 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 )
# Works correctly if script is sourced from another one DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd -P "$( dirname "${BASH_SOURCE[0]}" )" && 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 [[ ]]
Bash double brackets Bash (extended test command) are safer and provides more features but they are not portable (and not sh compatible). Features:
- not filename expansion. Strings will be take literally (i.e. “name*”).
- operators like || instead of -o
- 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