pwd # print working dir ls -la # list all with details ls -lh # human readable sizes cd ~/projects # go to home/projects cd .. # go up one level cd - # go to previous dir mkdir -p a/b/c # create nested dirs cp src dst # copy file cp -r dir1 dir2 # copy directory mv old new # move/rename rm file # remove file rm -rf dir # remove dir (careful!) touch file.txt # create empty file ln -s target link # symbolic link
cat file.txt # print file less file.txt # page through (q=quit) head -20 file.txt # first 20 lines tail -20 file.txt # last 20 lines tail -f log.txt # follow (live log) wc -l file.txt # count lines wc -w file.txt # count words # Find files find . -name "*.py" # by name find . -name "*.py" -newer x # newer than x find . -type f -size +10M # large files find . -mtime -7 # modified <7 days # Search content grep "pattern" file.txt # basic grep -r "pattern" dir/ # recursive grep -i "case" file # ignore case grep -n "pattern" file # show line num grep -v "exclude" file # invert match
# sed — stream editor
sed 's/old/new/' file # replace first
sed 's/old/new/g' file # replace all
sed -i 's/old/new/g' file # in-place
sed '/pattern/d' file # delete lines
sed -n '5,10p' file # print lines 5-10
# awk — text processing
awk '{print $1}' file # first column
awk '{print $NF}' file # last column
awk -F: '{print $1}' /etc/passwd
awk '{sum+=$2} END{print sum}' # sum col2
awk '$3>100 {print $0}' # filter rows
# cut, sort, uniq
cut -d',' -f1,3 csv.txt # columns 1,3
sort file.txt # sort lines
sort -n nums.txt # numeric sort
sort -k2 -r data.txt # by col2, reverse
uniq file.txt # remove adj dupes
sort | uniq -c | sort -rn # freq count
# Pipe: stdout of left → stdin of right cat file | grep "pattern" | wc -l # Redirect cmd > output.txt # stdout to file (overwrite) cmd >> output.txt # stdout to file (append) cmd 2> err.txt # stderr to file cmd &> all.txt # both to file cmd 2>&1 | tee log # stdout+err to pipe+file # Here document cat > file.txt << EOF line 1 line 2 EOF # Process substitution diff <(sort file1) <(sort file2) # tee — write to file and stdout ls -la | tee output.txt
#!/bin/bash
NAME="Alice" # assign (no spaces)
echo $NAME # use variable
echo "${NAME}_suffix" # safe expansion
# Command substitution
DATE=$(date +%Y-%m-%d)
FILES=$(find . -name "*.py")
# Arithmetic
COUNT=$((COUNT + 1))
$((5 * 3)) # 15
# Special variables
$0 # script name
$1 # first argument
$@ # all arguments
$# # argument count
$? # exit code of last command
$$ # current process ID
$! # PID of last background job
# Conditional
if [ $# -eq 0 ]; then
echo "No args"; exit 1
fi
[ -f file ] && echo "exists" # file exists
[ -d dir ] || mkdir dir # dir doesn't exist
# For loop
for f in *.py; do
echo "Processing $f"
python "$f"
done
for i in {1..10}; do echo $i; done
# While loop
while IFS= read -r line; do
echo "$line"
done < file.txt
# Until
until ping -c1 host &>/dev/null; do
sleep 5
done
# Functions
deploy() {
local env=$1 # local variable
echo "Deploying to $env"
git push "$env" main
}
deploy production
# Exit codes
exit 0 # success
exit 1 # general error
command && echo "ok" || echo "failed"
# chmod chmod +x script.sh # add execute chmod 644 file.txt # rw-r--r-- chmod 755 dir/ # rwxr-xr-x chmod -R 755 dir/ # recursive # chown chown user:group file # change owner sudo chown -R www-data /var/www # SSH ssh user@host # connect ssh -i key.pem user@host # with key scp local user@host:path # copy to remote rsync -av src/ user@host:dst/ # SSH config (~/.ssh/config) Host myserver HostName 1.2.3.4 User ubuntu IdentityFile ~/.ssh/my-key.pem # Cron (crontab -e) # MIN HOUR DOM MON DOW CMD 0 2 * * * /path/to/script.sh # daily 2am */5 * * * * /path/run.sh # every 5 min 0 9 * * 1 /weekly.sh # Monday 9am