#!/bin/bash | Bash shebang (first line of script) |
#!/usr/bin/env bash | Portable shebang |
chmod +x script.sh | Make script executable |
./script.sh | Run script in current directory |
bash script.sh | Run script with bash |
source script.sh | Run script in current shell |
. script.sh | Same as source (shorthand) |
# comment | Single line comment |
set -x | Enable debug mode (print commands) |
set +x | Disable debug mode |
set -e | Exit on error |
set -u | Error on undefined variables |
set -o pipefail | Pipeline fails if any command fails |
name="value" | Assign variable (no spaces around =) |
$name or ${name} | Use variable |
readonly name="value" | Read-only variable (constant) |
unset name | Delete variable |
local name="value" | Local variable (inside function) |
export name="value" | Export to environment |
declare -i num=5 | Declare integer variable |
$0 | Script name |
$1, $2, ... | Positional parameters (arguments) |
$# | Number of arguments |
$@ | All arguments (as separate words) |
$* | All arguments (as single string) |
$? | Exit status of last command |
$$ | Current process ID |
$! | PID of last background process |
${var:-default} | Use default if var is unset |
${var:=default} | Assign default if var is unset |
${var:+value} | Use value if var is set |
${var:?error} | Error if var is unset |
${#var} | Length of variable |
${var^^} | All uppercase |
${var,,} | All lowercase |
"double quotes" | Allows variable expansion |
'single quotes' | Literal string (no expansion) |
${var:0:5} | Substring from position 0, length 5 |
${var:7} | Substring from position 7 to end |
${var: -4} | Last 4 characters (note the space) |
${var/old/new} | Replace first occurrence |
${var//old/new} | Replace all occurrences |
${var#pattern} | Remove shortest match from start |
${var##pattern} | Remove longest match from start |
${var%pattern} | Remove shortest match from end |
${var%%pattern} | Remove longest match from end |
${file%.txt} | Example: remove .txt extension |
${path##*/} | Example: get filename from path |
arr=(a b c d) | Create array |
arr[0]="value" | Set element at index |
${arr[0]} | Get element at index |
${arr[@]} | All elements |
${#arr[@]} | Array length |
${!arr[@]} | All indices |
arr+=(e f) | Append elements |
unset arr[1] | Delete element at index |
declare -A map | Declare associative array |
map[key]="value" | Set key-value pair |
${map[key]} | Get value by key |
${!map[@]} | All keys |
${map[@]} | All values |
unset map[key] | Delete key-value pair |
if [[ condition ]]; then ... fi | Basic if statement |
if [[ cond ]]; then ... else ... fi | If-else statement |
if [[ cond1 ]]; then ... elif [[ cond2 ]]; then ... fi | If-elif statement |
[[ cond ]] && cmd | Short-hand if (and) |
[[ cond ]] || cmd | Short-hand if not (or) |
[[ -z "$str" ]] | String is empty |
[[ -n "$str" ]] | String is not empty |
[[ "$a" == "$b" ]] | Strings are equal |
[[ "$a" != "$b" ]] | Strings are not equal |
[[ "$str" =~ regex ]] | Regex match |
[[ "$str" == pattern* ]] | Pattern match (glob) |
[[ $a -eq $b ]] | Equal |
[[ $a -ne $b ]] | Not equal |
[[ $a -lt $b ]] | Less than |
[[ $a -le $b ]] | Less than or equal |
[[ $a -gt $b ]] | Greater than |
[[ $a -ge $b ]] | Greater than or equal |
(( a == b )) | Arithmetic comparison |
[[ -e "$file" ]] | File exists |
[[ -f "$file" ]] | Is regular file |
[[ -d "$dir" ]] | Is directory |
[[ -s "$file" ]] | File is not empty |
[[ -r "$file" ]] | File is readable |
[[ -w "$file" ]] | File is writable |
[[ -x "$file" ]] | File is executable |
[[ -L "$file" ]] | Is symbolic link |
for i in 1 2 3; do echo $i; done | Basic for loop |
for i in {1..10}; do | Range (1 to 10) |
for i in {1..10..2}; do | Range with step (1,3,5,7,9) |
for file in *.txt; do | Loop over files |
for arg in "$@"; do | Loop over arguments |
for ((i=0; i<10; i++)); do | C-style for loop |
while [[ cond ]]; do ... done | While loop |
until [[ cond ]]; do ... done | Until loop (opposite of while) |
while true; do | Infinite loop |
while read -r line; do ... done < file.txt | Read file line by line |
while IFS= read -r line; do | Preserve whitespace while reading |
break | Exit loop |
break 2 | Exit 2 levels of loops |
continue | Skip to next iteration |
continue 2 | Continue outer loop |
case $var in pattern1) cmd1 ;; pattern2) cmd2 ;; *) default ;; esac | Case statement structure |
a|b|c) | Match multiple patterns |
*.txt) | Glob pattern matching |
[0-9]*) | Range pattern |
;; | End case block (break) |
;& | Fall through to next case |
select opt in opt1 opt2 opt3; do ... break; done | Interactive menu |
$REPLY | User input number in select |
PS3="Choose: " | Custom prompt for select |
function name() { ... } | Function with keyword |
name() { ... } | Function shorthand |
local var="value" | Local variable inside function |
return 0 | Return exit status (0-255) |
echo "result" | Return value via stdout |
$1, $2, ... | Function arguments |
$# | Number of arguments |
$@ | All arguments |
shift | Shift arguments left by 1 |
shift 2 | Shift arguments left by 2 |
result=$(func arg1 arg2) | Capture function output |
read var | Read into variable |
read -p "Prompt: " var | Read with prompt |
read -s password | Read silently (for passwords) |
read -t 5 var | Read with 5 second timeout |
read -n 1 char | Read single character |
read -a arr | Read into array |
read -r line | Read raw (no backslash escape) |
echo "text" | Print with newline |
echo -n "text" | Print without newline |
echo -e "a\tb\n" | Enable escape sequences |
printf "%s\n" "$var" | Formatted print |
printf "%-10s %d\n" "name" 42 | Printf with formatting |
cmd > file | Redirect stdout to file (overwrite) |
cmd >> file | Redirect stdout to file (append) |
cmd 2> file | Redirect stderr to file |
cmd &> file | Redirect both stdout and stderr |
cmd 2>&1 | Redirect stderr to stdout |
cmd < file | Read stdin from file |
cmd <<< "string" | Here-string |
$((a + b)) | Addition |
$((a - b)) | Subtraction |
$((a * b)) | Multiplication |
$((a / b)) | Division (integer) |
$((a % b)) | Modulo (remainder) |
$((a ** b)) | Exponentiation |
((a++)) | Increment |
((a--)) | Decrement |
((a += 5)) | Add and assign |
echo 'scale=2; 5/3' | bc | Division with 2 decimal places |
echo 'sqrt(2)' | bc -l | Square root with math library |
result=$(echo "$a + $b" | bc) | Floating point addition |
$(command) | Command substitution (preferred) |
`command` | Command substitution (legacy) |
files=$(ls *.txt) | Store command output |
echo "Date: $(date)" | Inline substitution |
( cd /tmp && cmd ) | Subshell (isolated environment) |
{ cmd1; cmd2; } | Command group (same shell) |
diff <(cmd1) <(cmd2) | Compare output of two commands |
while read line; do ... done < <(cmd) | Read from process output |
cmd > >(tee file) | Write to process |
/etc/profile | System-wide login shell config |
/etc/bash.bashrc | System-wide interactive shell config |
~/.bash_profile | User login shell config |
~/.bashrc | User interactive shell config |
~/.bash_logout | Executed on logout |
source ~/.bashrc | Reload bashrc |
export PATH="$PATH:/new/path" | Add to PATH |
export EDITOR="vim" | Set default editor |
alias ll="ls -la" | Create alias |
alias rm="rm -i" | Safe rm alias |
HISTSIZE=10000 | History size in memory |
HISTFILESIZE=20000 | History file size |
PS1="\u@\h:\w\$ " | Custom prompt |
\u | Username |
\h | Hostname (short) |
\H | Hostname (full) |
\w | Current directory (full) |
\W | Current directory (basename) |
\d | Date |
\t | Time (24-hour) |
#!/usr/bin/env bash; set -euo pipefail | Safe script header (strict mode) |
"$var" | Always quote variables |
[[ ]] vs [ ] | Prefer [[ ]] (more features, safer) |
$(cmd) vs `cmd` | Prefer $() (nestable, clearer) |
readonly CONST="value" | Use readonly for constants |
local var | Use local variables in functions |
shellcheck script.sh | Use ShellCheck for linting |
cmd || { echo "Error"; exit 1; } | Error handling pattern |
trap "cleanup" EXIT | Cleanup on exit |
trap "echo Interrupted; exit" INT | Handle Ctrl+C |
mktemp | Create temp file safely |
mktemp -d | Create temp directory safely |
cd "$(dirname "$0")" | Go to script directory |