readarray -t var < <(command)
var=()
while IFS= read -r line; do
var+=( "$line" )
done < <(command)
IFS=" " read -r -a var <<< "$(command)"
readarray -t var < /path/to/file
var=()
while IFS= read -r line; do
var+=( "$line" )
done < /path/to/file
bc <<< "scale=4;$used/$available"
https://www.tldp.org/LDP/abs/html/parameter-substitution.html
${name} # the value
${name-default} # the value if set, or else default
${name:-default} # the value if set and non-empty, or else default
${name=default} # the value if set, or else default and assign it
${name:=default} # the value if set and non-empty, or else default
# and assign it
${name+alt} # alt if set, or else empty
${name:+alt} # alt if set and non-empty, or else default
${name?msg} # the value if set, or else echo msg and exit 1
${name:?msg} # the value if set and non-empty, or else echo msg
# and exit 1
${#name} # length of value or first element in array
${name#pattern} # value with shortest pattern removed from front
${name##pattern} # value with longest pattern removed from front
${name%pattern} # value with shortest pattern removed from back
${name%%pattern} # value with longest pattern removed from back
${name:pos} # value starting at offset pos
${name:pos:len} # value starting at offset pos for length len
${name/pat/rep} # value replacing first pat with rep
${name//pat/rep} # value replacing all pat with rep
${name/#pat/rep} # value replacing prefix pat with rep
${name/%pat/rep} # value replacing suffix pat with rep
${!name} # value of variable named ${name} (indirect)
${!n*} # names of variables starting with n
${!n@} # same
Colors: https://www.shellhacks.com/bash-colors/
RED="\033[0;31m"
DEFAULT="\033[0m"
echo -e "${RED}Red text${DEFAULT}"
Font decorations:
- 0 = normal
- 1 = bold
- 4 = underlined
- 5 = blinking
- 7 = reverse video
Colors (fg=3x, bg=4x):
- 30 = black -> dark gray (bolded)
- 31 = red -> light red
- 32 = green -> light green
- 33 = brown -> yellow
- 34 = blue -> light blue
- 35 = purple -> light purple
- 36 = cyan -> light cyan
- 37 = light gray -> white
read -r -d '' VAR <<EOF
contents
of
string
EOF
When set -e
is on, read returns 1 here and will exit the script.
read -p 'Enter the thing: ' var
echo "You entered $var"
- -r causes backslashes to be literal - shellcheck wants it
- -s stops echoes
- -n x returns after x characters automatically
read -p "Did you run all relevant unit tests? [y|n] " -n 1 -r < /dev/tty
echo
if echo "$REPLY" | grep -v -E '^[Yy]$' > /dev/null; then
echo "You said no"
else
echo "You said yes"
fi
cat >> path/to/file <<EOF
file
contents
here
EOF
eval "cat <<EOF
$(<path/to/fromfile)
EOF
" > path/to/tofile
declare -A aa
aa[foo]=bar
aa=([foo]=bar ...)
aa+=([baz]=blat ...)
echo ${aa[foo]}
for i in "${!aa[@]}" # each key
do
echo "key : $i"
echo "value: ${aa[$i]}"
done
if [ ${aa[foo]+_} ]; then echo foo is there; fi # param expansion
if [[ -z ${aa[foo]:+_} ]]; then echo foo is not there; fi
echo Size is "${#aa[@]}"
unset aa[foo]
For a directory
WORKDIR=$(mktemp -d)
trap "rm -rf "'"'"${WORKDIR}"'"' EXIT
For a file
WORKFILE=$(mktemp -t prefix)
trap "rm -f "'"'"${WORKFILE}"'"' EXIT
[[ $string =~ tar\.gz$ ]] && echo "It's a tarball"
man 3 regex
gives you the full syntax. So you can use [[:space:]]
for whitespace, for example.
Or you can use globs with ==
[[ $string == *tar.gz ]] && echo "It's a tarball"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
See https://stackoverflow.com/questions/3685970 for alternatives when elements have spaces in them.
if [[ " ${array[@]} " =~ " ${value} " ]]; then
# whatever you want to do when array contains value
fi
contains() {
local el
local target="$1"
shift
for el; do
if [[ "$el" == "$target" ]]; then
return 0
fi
done
return 1
}
IFS=',' read -ra MY_ARR <<< "this,that,other"
readarray -t sorted < <(printf '%s\n' "${array[@]}" | sort)
readarray -t sorted < <(printf '%s\0' "${array[@]}" | sort -z | xargs -0n1) # to cope with newlines
if ! command -v xyz; then
fail
fi
Can use hash
for regular commands, type
for built-ins and keywords
- -a file = file exists
- -b file = file exists and is block special
- -c file = file exists and is character special
- -d file = file exists and is directory
- -e file = file exists
- -f file = file exists and is regular
- -g file = file exists and has set-group-id bit set
- -h file = file exists and is symlink
- -k file = file exists and has sticky bit set
- -p file = file exists and is named pipe / fifo
- -r file = file exists and is readable
- -s file = file exists and has size greater than zero
- -t fd = fd is open and refers to terminal
- -u file = file exists and has set-user-id bit set
- -w file = file exists and is writable
- -x file = file exists and is executable
- -G file = file exists and owned by effective group id
- -L file = file exists and is symlink
- -N file = file exists and was modified since last read
- -O file = file exists and owned by effective user id
- -S file = file exists and is socket
- file1 -ef file2 = refer to same device and inode
- file1 -nt file2 = file1 newer than file2, or file1 exists and file2 doesn't
- file1 -ot file2 = file1 older than file2, or file2 exists and file1 doesn't
- -o optname = shell option enabled
- -v varname = shell variable set
- -R varname = shell variable set to name reference
- -z string = string has zero length
- -n string = string has non-zero length
- string = string has non-zero length
- string1 == string 2 = strings are equal
- string1 = string2 = strings are equal
- string1 != string2 = strings are not equal
- string1 < string2 = string1 lexicographically before
- string1 > string2 = string1 lexicographically after
- int1 [-eq|-ne|-lt|-le|-gt|-ge] int2 = int comparison