$# Number of arguments
$* All arguments
$@ All arguments, starting from first
$1 First argument
$_ Last argument of the previous command${FOO:-val} $FOO, or val if not set
${FOO:=val} Set $FOO to val if not set
${FOO:+val} val if $FOO is set
${FOO:?message} Show error message and exit if $FOO is not setThe :is optional (eg, ${FOO=word} works).
$((a + 200)) # Add 200 to $a
$((RANDOM%=200)) # Random number 0..200name="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"STR="/path/to/foo.cpp"
echo ${STR%.cpp} # /path/to/foo
echo ${STR%.cpp}.o # /path/to/foo.o
echo ${STR##*.} # cpp (extension)
echo ${STR##*/} # foo.cpp (basepath)
echo ${STR#*/} # path/to/foo.cpp
echo ${STR##*/} # foo.cpp
echo ${STR/foo/bar} # /path/to/bar.cppSTR="Hello world"
echo ${STR:6:5} # "world"
echo ${STR:-5:5} # "world"SRC="/path/to/foo.cpp"
BASE=${SRC##*/} #=> "foo.cpp" (basepath)
DIR=${SRC%$BASE} #=> "/path/to/" (dirpath)$? Exit status of last task
$! PID of last background task
$$ PID of shell
$0 Filename of the shell scriptSTR="HELLO WORLD!"
echo ${STR,} #=> "hELLO WORLD!" (lowercase 1st letter)
echo ${STR,,} #=> "hello world!" (all lowercase)STR="hello world!"
echo ${STR^} #=> "Hello world!" (uppercase 1st letter)
echo ${STR^^} #=> "HELLO WORLD!" (all uppercase)${#FOO} Length of $FOO${FOO:0:3} Substring (position, length)
${FOO:-3:3} Substring from the right${FOO%suffix} Remove suffix
${FOO#prefix} Remove prefix
${FOO%%suffix} Remove long suffix
${FOO##prefix} Remove long prefix
${FOO/from/to} Replace first match
${FOO//from/to} Replace all
${FOO/%from/to} Replace suffix
${FOO/#from/to} Replace prefixNote 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.
[[ -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
[[ -o noclobber ]] If OPTIONNAME is enabled
[[ ! EXPR ]] Not
[[ X ]] && [[ Y ]] And
[[ X ]] || [[ Y ]] Or[[ -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 filesFruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple"
Fruits[1]="Banana"
Fruits[2]="Orange"echo ${Fruits[0]} # Element #0
echo ${Fruits[@]} # All elements, space-separated
echo ${#Fruits[@]} # Number of elements
echo ${#Fruits} # String length of the 1st element
echo ${#Fruits[3]} # String length of the Nth element
echo ${Fruits[@]:3:2} # Range (from position 3, length 2)Fruits=("${Fruits[@]}" "Watermelon") # Push
Fruits+=('Watermelon') # Also Push
Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match
unset Fruits[2] # Remove one item
Fruits=("${Fruits[@]}") # Duplicate
Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
lines=(`cat "logfile"`) # Read from filefor i in "${arrayName[@]}"; do
echo $i
donedeclare -A sounds
sounds[dog]="bark"
sounds[cow]="moo"
sounds[bird]="tweet"
sounds[wolf]="howl"echo ${sounds[dog]} # Dog's sound
echo ${sounds[@]} # All values
echo ${!sounds[@]} # All keys
echo ${#sounds[@]} # Number of elements
unset sounds[dog] # Delete dogfor val in "${sounds[@]}"; do
echo $val
donefor key in "${!sounds[@]}"; do
echo $key
donehdparm -tT /dev/sda Perform a read speed test on disk sdatcpdump -i eth0 Capture and display all packets on interface eth0
tcpdump -i eth0 'port 80' Monitor all traffic on port 80 (HTTP)find /dir/ -name name* Find files starting with name in dir
find /dir/ -user name Find files owned by name in dir
find /dir/ -mmin num Find files modifed less than num minutes ago in dir
find /home/john -name 'prefix*' Find files in /home/john that start with "prefix".
find /home -size +100M Find files larger than 100MB in /homelsof -u user List files opened by user
cmd < file Input of cmd from file
cmd1 <(cmd2) Output of cmd2 as file input to cmd1
cmd > file Standard output (stdout) of cmd to file
cmd > /dev/null Discard stdout of cmd
cmd >> file Append stdout to file
cmd 2> file Error output (stderr) of cmd to file
cmd 1>&2 stdout to same place as stderr
cmd 2>&1 stderr to same place as stdout
cmd &> file Every output of cmd to file cmd refers to a command.for i in /etc/rc.*; do
echo $i
donefor ((i = 0 ; i < 100 ; i++)); do
echo $i
donefor i in {1..5}; do
echo "Welcome $i"
donefor i in {5..50..5}; do
echo "Welcome $i"
donewhile :; do
echo "Press [CTRL+C] to stop.."
sleep 1
donewhile true; do
echo "Press [CTRL+C] to stop.."
sleep 1
donewhile :; do echo 'Hit CTRL+C'; sleep 1; donewhile true; do echo 'Hit CTRL+C'; sleep 1; donefor (( ; ; )); do
echo "Pres CTRL+C to stop..."
sleep 1
donefor (( ; ; )); do
echo "Pres CTRL+C to stop..."
sleep 1
if (disaster-condition); then
break
fi
donecase "$1" in
start | up)
vagrant up
;;
*)
echo "Usage: $0 {start|stop|ssh}"
;;
esacDIR="${0%/*}"while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do
case $1 in
-V | --version ) echo $version; exit ;;
-s | --string ) shift; string=$1 ;;
-f | --flag ) flag=1 ;;
esac; shift;
done
if [[ "$1" == '--' ]]; then shift; ficat <<END
hello world
ENDsource "${0%/*}/../share/foo.sh"cmd1 | cmd2 stdout of cmd1 to cmd2
cmd1 |& cmd2 stderr of cmd1 to cmd2myfunc() {
local myresult='some value'
echo $myresult
}
result="$(myfunc)"useradd -c "John Smith" -m john Create an account named john, with a comment of "John Smith" and create the user's home directory.
usermod -aG sales john Add the john account to the sales group