Variables, loops, conditionals, functions, pipes, redirection & scripting
Linux / Shell# Assignment (no spaces around =)
NAME="Alice"
AGE=25
readonly PI=3.14
export PATH="$PATH:/usr/local/bin"
# Interpolation & quoting
echo "Hello, $NAME" # expands
echo 'Hello, $NAME' # literal
echo "Length: ${#NAME}" # 5
echo "${NAME,,}" # lowercase
echo "${NAME^^}" # uppercase
echo "${NAME:0:3}" # substring → Ali
echo "${NAME/li/LI}" # replace → ALIce
# Defaults
echo "${VAR:-default}" # use default if unset
echo "${VAR:=default}" # set & use if unset
# Special variables
$0 # script name $1 # 1st arg $# # arg count
$@ # all args $? # exit status
$$ # current PID $! # last bg PID# Indexed array
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}" # apple
echo "${fruits[@]}" # all
echo "${#fruits[@]}" # length
fruits+=("date") # append
unset fruits[1]
# Associative array (bash 4+)
declare -A colors
colors[red]="#ff0000"
echo "${!colors[@]}" # keys
# Iterate
for f in "${fruits[@]}"; do echo "$f"; doneif [[ "$NAME" == "Alice" ]]; then
echo "Hi Alice"
elif [[ "$AGE" -gt 18 ]]; then
echo "Adult"
else
echo "Minor"
fi
# Operators
-eq -ne -lt -gt -le -ge # numeric
== != < > # string
-z "$a" # empty -n "$a" # not empty
&& || ! # logical
# Case
case "$1" in
start) echo "Starting" ;;
stop) echo "Stopping" ;;
*) echo "Usage: $0 {start|stop}" ;;
esacfor i in 1 2 3; do echo "$i"; done
for i in {1..10}; do echo "$i"; done
for ((i=0; i<10; i++)); do echo "$i"; done
# While / Until
while [[ "$c" -lt 5 ]]; do ((c++)); done
until [[ "$s" == "ready" ]]; do sleep 1; done
# Read file line by line
while IFS= read -r line; do
echo "$line"
done < file.txtgreet() {
local name="$1"
echo "Hello, $name!"
return 0
}
greet "Alice"
# Capture output
add() { echo $(( $1 + $2 )); }
result=$(add 3 4)
# Error handling
set -euo pipefail
trap "echo Error on line $LINENO" ERR
trap cleanup EXITcmd > file.txt # overwrite
cmd >> file.txt # append
cmd < file.txt # stdin from file
cmd 2> err.log # stderr to file
cmd &> all.log # stdout+stderr
cmd > /dev/null 2>&1 # discard all
# Here document
cat <<EOF
Hello $NAME
EOF
# Here string
grep "pat" <<< "search this"
# Process substitution
diff <(ls dir1) <(ls dir2)cat f.txt | grep "err" | wc -l
ps aux | grep "node" | awk '{print $2}'
find . -name "*.tmp" | xargs rm -f
# Command substitution
today=$(date +%Y-%m-%d)
# Background jobs
long_cmd &
jobs fg %1 wait
# Subshell (doesn't affect parent)
(cd /tmp && ls)str="Hello World"
echo "${str:6}" # World
echo "${str:0:5}" # Hello
file="archive.tar.gz"
echo "${file%.*}" # archive.tar (shortest from end)
echo "${file%%.*}" # archive (longest from end)
echo "${file#*.}" # tar.gz (shortest from start)
echo "${file##*.}" # gz (longest from start)
echo "${str/World/Bash}" # Hello Bash (first)
echo "${str//l/L}" # HeLLo WorLd (all)[[ -f "f" ]] # regular file
[[ -d "d" ]] # directory
[[ -e "p" ]] # exists
[[ -r "f" ]] # readable
[[ -w "f" ]] # writable
[[ -x "f" ]] # executable
[[ -s "f" ]] # not empty
[[ -L "f" ]] # symlink
[[ "$a" -nt "$b" ]] # newer than# Count lines in *.py
find . -name "*.py" -exec wc -l {} + | tail -1
# Parallel download
cat urls.txt | xargs -P 4 -I {} curl -sO {}
# Quick server
python3 -m http.server 8080
# Largest files
du -ah . | sort -rh | head -20
# Replace in files
find . -name "*.txt" -exec sed -i 's/old/new/g' {} +
# Monitor log
tail -f /var/log/syslog | grep --line-buffered "error"