Shell手册
- Getting started
- Parameter expansions
- Loops
- Functions
- Conditionals
- Arrays
- Dictionaries
- Options
- History
- Miscellaneous
- Also see
Getting started
This is a quick reference to getting started with Bash scripting.
- Learn bash in y minutes (learnxinyminutes.com)
- Bash Guide (mywiki.wooledge.org)
Example
Variables
String quotes
Shell execution
Conditional execution
Functions Example
See: Functions
Conditionals example
1if [[ -z "$string" ]]; then
2 echo "String is empty"
3elif [[ -n "$string" ]]; then
4 echo "String is not empty"
5fi
See: Conditionals
Strict mode
See: Unofficial bash strict mode
Brace expansion
Expression | Description |
---|---|
{A,B} |
Same as A B |
{A,B}.js |
Same as A.js B.js |
{1..5} |
Same as 1 2 3 4 5 |
See: Brace expansion
Parameter expansions
Basics
1name="John"
2echo ${name}
3echo ${name/J/j} #=> "john" (substitution)
4echo ${name:0:2} #=> "Jo" (slicing)
5echo ${name::2} #=> "Jo" (slicing)
6echo ${name::-1} #=> "Joh" (slicing)
7echo ${name:(-1)} #=> "n" (slicing from right)
8echo ${name:(-2):1} #=> "h" (slicing from right)
9echo ${food:-Cake} #=> $food or "Cake"
See: Parameter expansion
1STR="/path/to/foo.cpp"
2echo ${STR%.cpp} # /path/to/foo
3echo ${STR%.cpp}.o # /path/to/foo.o
4echo ${STR%/*} # /path/to
5
6echo ${STR##*.} # cpp (extension)
7echo ${STR##*/} # foo.cpp (basepath)
8
9echo ${STR#*/} # path/to/foo.cpp
10echo ${STR##*/} # foo.cpp
11
12echo ${STR/foo/bar} # /path/to/bar.cpp
1SRC="/path/to/foo.cpp"
2BASE=${SRC##*/} #=> "foo.cpp" (basepath)
3DIR=${SRC%$BASE} #=> "/path/to/" (dirpath)
Substitution
Code | Description |
---|---|
${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 prefix |
Comments
Substrings
Expression | Description |
---|---|
${FOO:0:3} |
Substring (position, length) |
${FOO:(-3):3} |
Substring from the right |
Length
Expression | Description |
---|---|
${#FOO} |
Length of $FOO |
Manipulation
1STR="HELLO WORLD!"
2echo ${STR,} #=> "hELLO WORLD!" (lowercase 1st letter)
3echo ${STR,,} #=> "hello world!" (all lowercase)
4
5STR="hello world!"
6echo ${STR^} #=> "Hello world!" (uppercase 1st letter)
7echo ${STR^^} #=> "HELLO WORLD!" (all uppercase)
Default values
Expression | Description |
---|---|
${FOO:-val} |
$FOO , or val if unset (or null) |
${FOO:=val} |
Set $FOO to val if unset (or null) |
${FOO:+val} |
val if $FOO is set (and not null) |
${FOO:?message} |
Show error message and exit if $FOO is unset (or null) |
Omitting the :
removes the (non)nullity checks, e.g. ${FOO-val}
expands to val
if unset otherwise $FOO
.
Loops
Basic for loop
C-like for loop
Ranges
With step size
Reading lines
Forever
Functions
Defining functions
Returning values
Raising errors
Arguments
Expression | Description |
---|---|
$# |
Number of arguments |
$* |
All positional arguments (as a single word) |
$@ |
All positional arguments (as separate strings) |
$1 |
First argument |
$_ |
Last argument of the previous command |
Note: $@
and $*
must be quoted in order to perform as described.
Otherwise, they do exactly the same thing (arguments as separate strings).
See Special parameters.
Conditionals
Conditions
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 |
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 |
Test Example
1# String
2if [[ -z "$string" ]]; then
3 echo "String is empty"
4elif [[ -n "$string" ]]; then
5 echo "String is not empty"
6else
7 echo "This never happens"
8fi
Arrays
Defining arrays
Working with arrays
1echo ${Fruits[0]} # Element #0
2echo ${Fruits[-1]} # Last element
3echo ${Fruits[@]} # All elements, space-separated
4echo ${#Fruits[@]} # Number of elements
5echo ${#Fruits} # String length of the 1st element
6echo ${#Fruits[3]} # String length of the Nth element
7echo ${Fruits[@]:3:2} # Range (from position 3, length 2)
8echo ${!Fruits[@]} # Keys of all elements, space-separated
Operations
1Fruits=("${Fruits[@]}" "Watermelon") # Push
2Fruits+=('Watermelon') # Also Push
3Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match
4unset Fruits[2] # Remove one item
5Fruits=("${Fruits[@]}") # Duplicate
6Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
7lines=(`cat "logfile"`) # Read from file
Iteration
Dictionaries
Defining
Declares sound
as a Dictionary object (aka associative array).
Working with dictionaries
1echo ${sounds[dog]} # Dog's sound
2echo ${sounds[@]} # All values
3echo ${!sounds[@]} # All keys
4echo ${#sounds[@]} # Number of elements
5unset sounds[dog] # Delete dog
Iteration Operation
Iterate over values
Iterate over keys
Options
set Options
1set -o noclobber # Avoid overlay files (echo "hi" > foo)
2set -o errexit # Used to exit upon error, avoiding cascading errors
3set -o pipefail # Unveils hidden failures
4set -o nounset # Exposes unset variables
Glob options
1shopt -s nullglob # Non-matching globs are removed ('*.foo' => '')
2shopt -s failglob # Non-matching globs throw errors
3shopt -s nocaseglob # Case insensitive globs
4shopt -s dotglob # Wildcards match dotfiles ("*.sh" => ".foo.sh")
5shopt -s globstar # 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 n th most recent command |
!n |
Expand n th command in history |
!<command> |
Expand most recent invocation of command <command> |
Operation Info
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 n th 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 n th token to last from most recent command |
!!
can be replaced with any valid expansion i.e. !cat
, !-2
, !42
, etc.
Miscellaneous
Numeric calculations
Subshells
Redirection
1python hello.py > output.txt # stdout to (file)
2python hello.py >> output.txt # stdout to (file), append
3python hello.py 2> error.log # stderr to (file)
4python hello.py 2>&1 # stderr to stdout
5python hello.py 2>/dev/null # stderr to (null)
6python hello.py &>/dev/null # stdout and stderr to (null)
Inspecting commands
Trap errors
or
1traperr() {
2 echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
3}
4
5set -o errtrace
6trap traperr ERR
Case/switch
1case "$1" in
2 start | up)
3 vagrant up
4 ;;
5
6 *)
7 echo "Usage: $0 {start|stop|ssh}"
8 ;;
9esac
Source relative
printf
1printf "Hello %s, I'm %s" Sven Olga
2#=> "Hello Sven, I'm Olga
3
4printf "1 + 1 = %d" 2
5#=> "1 + 1 = 2"
6
7printf "This is how you print a float: %f" 2
8#=> "This is how you print a float: 2.000000"
Directory of script
Getting options
1while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
2 -V | --version )
3 echo $version
4 exit
5 ;;
6 -s | --string )
7 shift; string=$1
8 ;;
9 -f | --flag )
10 flag=1
11 ;;
12esac; shift; done
13if [[ "$1" == '--' ]]; then shift; fi
Heredoc
Reading input
Special variables
Expression | Description |
---|---|
$? |
Exit status of last task |
$! |
PID of last background task |
$$ |
PID of shell |
$0 |
Filename of the shell script |
$_ |
Last argrument of the previous command |
See Special parameters.
Go to previous directory
Check for command's result
Grep check
1if grep -q 'foo' ~/.bash_history; then
2 echo "You appear to have typed 'foo' in the past"
3fi
Also see
- Bash-hackers wiki (bash-hackers.org)
- Shell vars (bash-hackers.org)
- Learn bash in y minutes (learnxinyminutes.com)
- Bash Guide (mywiki.wooledge.org)
- ShellCheck (shellcheck.net)