bash
GNU Bourne-Again Shell usage guide.
History Expansion
Reuse parts of previous commands to speed up your workflow.
| Command | Description |
|---|---|
!! | Run the last command again. |
!n | Run the nth command from history. |
!$ | Last argument of the last command. |
!^ | First argument of the last command. |
!* | All arguments of the last command. |
!:n | The nth argument of the last command. |
!string | Run the most recent command starting with string. |
!?string? | Run the most recent command containing string. |
^old^new | Replace old with new in the previous command and run it. |
Brace Expansion
Generate arbitrary strings.
echo filename{,.bak}
Create directory structure.
mkdir -p project/{src,test,doc}/{html,pdf}
Generate ranges.
echo {1..10}
Generate letter ranges.
echo {a..z}
Parameter Expansion
Manipulate variables without external tools like sed or awk.
| Syntax | Description |
|---|---|
${var:-default} | Use default if var is unset or null. |
${var:=default} | Set var to default if unset or null. |
${var:?error} | Exit with error if var is unset or null. |
${#var} | Length of the variable. |
${var:offset:length} | Substring. |
${var#pattern} | Remove shortest match of pattern from front. |
${var##pattern} | Remove longest match of pattern from front. |
${var%pattern} | Remove shortest match of pattern from back. |
${var%%pattern} | Remove longest match of pattern from back. |
${var/pattern/replace} | Replace first match. |
${var//pattern/replace} | Replace all matches. |
${var^} | Uppercase first character. |
${var^^} | Uppercase all characters. |
${var,} | Lowercase first character. |
${var,,} | Lowercase all characters. |
Arrays
Indexed Arrays
Declare an indexed array.
arr=(one two three)
Read the first element.
echo "${arr[0]}"
Read all elements.
echo "${arr[@]}" # All elements
Read the array length.
echo "${#arr[@]}" # Array length
Read all array indices.
echo "${!arr[@]}" # All indices
Append an element.
arr+=(four)
Delete one element.
unset "arr[1]"
Associative Arrays (Bash 4.0+)
declare -A map
map[foo]="bar"
map[baz]="qux"
echo "${map[foo]}"
Special Variables
Commonly used special shell variables.
| Variable | Description |
|---|---|
$0 | Name of the script. |
$1 - $9 | Arguments passed to the script. |
$# | Number of arguments passed to the script. |
$@ | All arguments passed to the script. |
$* | All arguments as a single string. |
$? | Exit status of the last command. |
$$ | Process ID of the current shell. |
$! | Process ID of the last background job. |
$_ | Last argument of the previous command. |
$- | Current set of options. |
Conditional Expressions
File Test Operators
| Operator | Description |
|---|---|
-e file | File exists. |
-f file | File is a regular file. |
-d file | File is a directory. |
-s file | File is not empty. |
-x file | File is executable. |
-w file | File is writable. |
-r file | File is readable. |
file1 -nt file2 | file1 is newer than file2. |
String & Integer Comparison
| Operator | Description |
|---|---|
-z str | String is empty (length 0). |
-n str | String is not empty. |
str1 == str2 | Strings are equal. |
str1 != str2 | Strings are not equal. |
int1 -eq int2 | Integers are equal. |
int1 -ne int2 | Integers are not equal. |
int1 -lt int2 | Less than. |
int1 -le int2 | Less than or equal. |
int1 -gt int2 | Greater than. |
int1 -ge int2 | Greater than or equal. |
Advanced Tests ([[ ]])
The [[ ... ]] construct is safer and more powerful than [ ... ].
Regex matching example.
if [[ $str =~ ^[0-9]+$ ]]; then
echo "Is a number"
fi
Pattern matching example.
if [[ $file == *.tar.gz ]]; then
echo "Is a tarball"
fi
Logical operator example.
if [[ -f $file && ! -s $file ]]; then
echo "File exists but is empty"
fi
Loops
For Loop
Iterate over a fixed list.
for item in one two three; do
echo "$item"
done
Use a C-style loop.
for ((i=0; i<10; i++)); do
echo "$i"
done
Iterate over a numeric range.
for i in {1..5}; do
echo "$i"
done
While Loop
count=0
while [[ $count -lt 5 ]]; do
echo "$count"
((count++))
done
Functions
Define reusable code blocks.
Use local to limit a variable to the function scope.
my_function() {
local var="local variable"
echo "Argument 1: $1"
return 0
}
my_function "hello"
💡 Tip: Always use
localfor variables inside functions to avoid polluting the global scope.
Built-in Commands
Colon (:)
The colon command is a built-in "true" null command that does nothing and always returns success (exit status 0).
Clear a file content without deleting the file:
:> file.txt
Process Substitution
Compare output of two commands.
diff <(ls dir1) <(ls dir2)
Loop over command output.
while read -r line; do echo "$line"; done < <(grep "something" file.txt)
Redirection & Pipes
| Syntax | Description |
|---|---|
cmd > file | Redirect stdout to file (overwrite). |
cmd >> file | Redirect stdout to file (append). |
cmd 2> file | Redirect stderr to file. |
cmd &> file | Redirect stdout and stderr to file. |
cmd > file 2>&1 | Same as &>. |
cmd < file | Redirect file to stdin. |
cmd <<< "str" | Here-string (pass string to stdin). |
cmd | tee file | Output to screen and file. |
Advanced Redirection
Write a here-document to a file.
cat <<EOF > file.txt
Multi-line
content
EOF
Close file descriptor 3.
exec 3>&-
Open a file for reading on file descriptor 3.
exec 3< file.txt
Keyboard Shortcuts
| Key | Action |
|---|---|
Ctrl + A | Go to beginning of line. |
Ctrl + E | Go to end of line. |
Ctrl + U | Cut from cursor to beginning of line. |
Ctrl + K | Cut from cursor to end of line. |
Ctrl + W | Cut previous word. |
Ctrl + Y | Paste (yank) what was cut. |
Ctrl + R | Search history backward. |
Alt + . | Insert last argument of previous command. |
Safety & Debugging
Strict Mode
Start your scripts with this to fail fast on errors.
set -euo pipefail
IFS=$'\n\t'
| Option | Description |
|---|---|
set -e | Exit immediately if a command exits with a non-zero status. |
set -u | Treat unset variables as an error. |
set -o pipefail | Return value of a pipeline is the value of the last command to exit with a non-zero status. |
set -x | Print commands and their arguments as they are executed (debug). |
Traps
Execute code when the script exits or receives a signal.
cleanup() {
rm -f /tmp/tempfile
}
trap cleanup EXIT
Job Control
Manage background processes.
| Command | Description |
|---|---|
cmd & | Run cmd in background. |
jobs | List background jobs. |
fg %1 | Bring job 1 to foreground. |
bg %1 | Resume job 1 in background. |
disown %1 | Remove job 1 from shell's job table. |
wait | Wait for all background jobs to finish. |
Resources
- GNU Bash Manual
- ShellCheck - Static analysis tool for shell scripts.
- Bash Hackers Wiki