name="John"echo"${name}"echo"${name/J/j}"#=> "john" (substitution)echo"${name:0:2}"#=> "Jo" (slicing)echo"${name::2}"#=> "Jo" (slicing)echo"${name::-1}"#=> "Joh" (slicing)echo"${name:(-1)}"#=> "n" (slicing from right)echo"${name:(-2):1}"#=> "h" (slicing from right)echo"${food:-Cake}"#=> $food or "Cake"
Note that [[ is actually a command/program that returns either 0 (true) or 1 (false). Any program that obeys the same logic (like all base utils, such as grep(1) or ping(1)) can be used as condition, see examples.
Condition
Description
[[ -z STRING ]]
Empty string
[[ -n STRING ]]
Not empty string
[[ STRING == STRING ]]
Equal
[[ STRING != STRING ]]
Not Equal
---
---
[[ NUM -eq NUM ]]
Equal
[[ NUM -ne NUM ]]
Not equal
[[ NUM -lt NUM ]]
Less than
[[ NUM -le NUM ]]
Less than or equal
[[ NUM -gt NUM ]]
Greater than
[[ NUM -ge NUM ]]
Greater than or equal
---
---
[[ STRING =~ STRING ]]
Regexp
---
---
(( NUM < NUM ))
Numeric conditions
More conditions
Condition
Description
[[ -o noclobber ]]
If OPTIONNAME is enabled
---
---
[[ ! EXPR ]]
Not
[[ X && Y ]]
And
[[ X || Y ]]
Or
File conditions
Condition
Description
[[ -e FILE ]]
Exists
[[ -r FILE ]]
Readable
[[ -h FILE ]]
Symlink
[[ -d FILE ]]
Directory
[[ -w FILE ]]
Writable
[[ -s FILE ]]
Size is > 0 bytes
[[ -f FILE ]]
File
[[ -x FILE ]]
Executable
---
---
[[ FILE1 -nt FILE2 ]]
1 is more recent than 2
[[ FILE1 -ot FILE2 ]]
2 is more recent than 1
[[ FILE1 -ef FILE2 ]]
Same files
Example
# Stringif[[-z"$string"]];thenecho"String is empty"elif[[-n"$string"]];thenecho"String is not empty"elseecho"This never happens"fi
echo"${Fruits[0]}"# Element #0echo"${Fruits[-1]}"# Last elementecho"${Fruits[@]}"# All elements, space-separatedecho"${#Fruits[@]}"# Number of elementsecho"${#Fruits}"# String length of the 1st elementecho"${#Fruits[3]}"# String length of the Nth elementecho"${Fruits[@]:3:2}"# Range (from position 3, length 2)echo"${!Fruits[@]}"# Keys of all elements, space-separated
Operations
Fruits=("${Fruits[@]}""Watermelon")# PushFruits+=('Watermelon')# Also PushFruits=("${Fruits[@]/Ap*/}")# Remove by regex matchunsetFruits[2]# Remove one itemFruits=("${Fruits[@]}")# DuplicateFruits=("${Fruits[@]}""${Veggies[@]}")# Concatenatelines=(`cat"logfile"`)# Read from file
Declares sound as a Dictionary object (aka associative array).
Working with dictionaries
echo"${sounds[dog]}"# Dog's soundecho"${sounds[@]}"# All valuesecho"${!sounds[@]}"# All keysecho"${#sounds[@]}"# Number of elementsunsetsounds[dog]# Delete dog
Iteration
Iterate over values
forvalin"${sounds[@]}";doecho"$val"done
Iterate over keys
forkeyin"${!sounds[@]}";doecho"$key"done
Options
set-onoclobber# Avoid overlay files (echo "hi" > foo)set-oerrexit# Used to exit upon error, avoiding cascading errorsset-opipefail# Unveils hidden failuresset-onounset# Exposes unset variables
Glob options
shopt-snullglob# Non-matching globs are removed ('*.foo' => '')shopt-sfailglob# Non-matching globs throw errorsshopt-snocaseglob# Case insensitive globsshopt-sdotglob# Wildcards match dotfiles ("*.sh" => ".foo.sh")shopt-sglobstar# Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')
Set GLOBIGNORE as a colon-separated list of patterns to be removed from glob
matches.
History
Commands
Command
Description
history
Show history
shopt -s histverify
Don't execute expanded result immediately
Expansions
Expression
Description
!$
Expand last parameter of most recent command
!*
Expand all parameters of most recent command
!-n
Expand nth most recent command
!n
Expand nth command in history
!<command>
Expand most recent invocation of command <command>
Operations
Code
Description
!!
Execute last command again
!!:s/<FROM>/<TO>/
Replace first occurrence of <FROM> to <TO> in most recent command
!!:gs/<FROM>/<TO>/
Replace all occurrences of <FROM> to <TO> in most recent command
!$:t
Expand only basename from last parameter of most recent command
!$:h
Expand only directory from last parameter of most recent command
!! and !$ can be replaced with any valid expansion.
Slices
Code
Description
!!:n
Expand only nth token from most recent command (command is 0; first argument is 1)
!^
Expand first argument from most recent command
!$
Expand last token from most recent command
!!:n-m
Expand range of tokens from most recent command
!!:n-$
Expand nth token to last from most recent command
!! can be replaced with any valid expansion i.e. !cat, !-2, !42, etc.
Miscellaneous
Numeric calculations
$((a+200))# Add 200 to $a
$(($RANDOM%200))# Random number 0..199
declare-icount# Declare as type integercount+=1# Increment
Subshells
(cdsomedir;echo"I'm now in $PWD")pwd# still in first directory
Redirection
pythonhello.py>output.txt# stdout to (file)pythonhello.py>>output.txt# stdout to (file), appendpythonhello.py2>error.log# stderr to (file)pythonhello.py2>&1# stderr to stdoutpythonhello.py2>/dev/null# stderr to (null)pythonhello.py>output.txt2>&1# stdout and stderr to (file), equivalent to &>pythonhello.py&>/dev/null# stdout and stderr to (null)echo"$0: warning: too many users">&2# print diagnostic message to stderr
pythonhello.py<foo.txt# feed foo.txt to stdin for pythondiff<(ls-r)<(ls)# Compare two stdout without files
Inspecting commands
command-Vcd#=> "cd is a function/alias/whatever"
Trap errors
trap'echo Error at about $LINENO'ERR
or
traperr(){echo"ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"}set-oerrtrace
traptraperrERR
printf"Hello %s, I'm %s"SvenOlga
#=> "Hello Sven, I'm Olgaprintf"1 + 1 = %d"2#=> "1 + 1 = 2"printf"This is how you print a float: %f"2#=> "This is how you print a float: 2.000000"printf'%s\n''#!/bin/bash''echo hello'>file
# format string is applied to each group of argumentsprintf'%i+%i=%i\n'123459
Transform strings
Command option
Description
-c
Operations apply to characters not in the given set
-d
Delete characters
-s
Replaces repeated characters with single occurrence
-t
Truncates
[:upper:]
All upper case letters
[:lower:]
All lower case letters
[:digit:]
All digits
[:space:]
All whitespace
[:alpha:]
All letters
[:alnum:]
All letters and digits
Example
echo"Welcome To Devhints"|tr'[:lower:]''[:upper:]'WELCOMETODEVHINTS