Language lab · Beginner → Ops
🐧 Linux administration
Concept → trace → write code → run tests → explain why → improve → mini-project. Start in the browser if you like; set up your own computer when you are ready.
📖 Topics with real code (17)
Every verified output below was produced by running the code with GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu) on 6 Nov 2026. Open a topic to edit the code and run it on your own computer with the real compiler, through the free GayaGnan agent.
🌱 Beginner (5)
Who am I and where am I
whoami, hostname, pwd and uname tell you the user, the machine, the current folder and the kernel. cd moves between folders; ~ is your home folder.
whoami hostname >/dev/null && echo "hostname works" cd /tmp && pwd uname -s -m echo "home is $HOME, shell is $SHELL"
✅ Verified output
root hostname works /tmp Linux x86_64 home is /root, shell is /bin/bash
Files and folders
mkdir -p creates nested folders, touch makes empty files, cp copies, mv moves or renames, rm deletes (there is no recycle bin). ls -l lists with details.
cd "$(mktemp -d)" mkdir -p project/src project/docs touch project/src/main.c project/README.md cp project/README.md project/docs/ mv project/src/main.c project/src/app.c ls -R project rm -r project/docs ls project
✅ Verified output
project: README.md docs src project/docs: README.md project/src: app.c README.md src
Reading files: cat, head, tail, wc
cat prints a file, head and tail show the start and end, wc counts lines, words and bytes. tail -f follows a log as it grows.
f=$(mktemp) printf 'line %s\n' 1 2 3 4 5 6 7 8 9 10 > "$f" head -n 3 "$f" echo ... tail -n 2 "$f" wc -l -w -c < "$f"
✅ Verified output
line 1 line 2 line 3 ... line 9 line 10 10 20 71
Permissions with chmod
Every file has read (r), write (w) and execute (x) for the owner, the group and others. chmod 750 = rwx for owner, r-x for group, nothing for others. A script needs x to run.
cd "$(mktemp -d)" printf '#!/bin/sh\necho hello from a script\n' > hello.sh ls -l hello.sh | cut -c1-10 ./hello.sh 2>&1 | head -1 || true chmod 750 hello.sh ls -l hello.sh | cut -c1-10 ./hello.sh stat -c '%a %A %n' hello.sh
✅ Verified output
-rw-r--r-- main.sh: line 4: ./hello.sh: Permission denied -rwxr-x--- hello from a script 750 -rwxr-x--- hello.sh
Searching text with grep
grep prints lines that match a pattern. -i ignores case, -n shows line numbers, -c counts, -v inverts, -E allows extended regular expressions.
f=$(mktemp) printf 'ERROR disk full\ninfo started\nWarning low memory\nerror timeout\ninfo done\n' > "$f" grep -n -i error "$f" echo "errors: $(grep -ci error "$f")" grep -v info "$f" grep -E '^(ERROR|Warning)' "$f"
✅ Verified output
1:ERROR disk full 4:error timeout errors: 2 ERROR disk full Warning low memory error timeout ERROR disk full Warning low memory
🌿 Intermediate (7)
Users and groups
id shows your user and groups. useradd creates a user, groupadd a group, usermod -aG adds a user to a group. /etc/passwd lists accounts (passwords live in /etc/shadow).
groupadd devs useradd -m -s /bin/bash -G devs asha id asha grep '^asha:' /etc/passwd | cut -d: -f1,6,7 getent group devs userdel -r asha 2>/dev/null; groupdel devs
✅ Verified output
uid=1000(asha) gid=1001(asha) groups=1001(asha),1000(devs) asha:/home/asha:/bin/bash devs:x:1000:asha
Ownership with chown
chown user:group file changes who owns a file. Only root can give files away. Together with permissions this decides who can read or change data.
useradd -m ravi f=/tmp/report.txt echo "quarterly figures" > "$f" chown ravi:ravi "$f" chmod 640 "$f" stat -c '%U:%G %A %n' "$f" su ravi -c "cat $f" rm -f "$f"; userdel -r ravi 2>/dev/null
✅ Verified output
ravi:ravi -rw-r----- /tmp/report.txt quarterly figures
Processes: ps, kill, background jobs
ps lists processes, & starts a job in the background, $! is its process ID, kill sends a signal (TERM asks politely, KILL forces).
sleep 60 & pid=$! ps -o pid=,comm= -p "$pid" kill -TERM "$pid" wait "$pid" 2>/dev/null echo "exit status $? (143 = 128 + SIGTERM 15)" ps -eo comm= | grep -c sleep || true
✅ Verified output
142 sleep exit status 143 (143 = 128 + SIGTERM 15) 1
Pipes and redirection
| sends output to the next command, > writes a file, >> appends, 2> redirects errors, 2>&1 merges errors into output. Small tools combine into powerful reports.
cd "$(mktemp -d)" printf '192.168.1.5 GET /\n10.0.0.2 GET /login\n192.168.1.5 POST /login\n10.0.0.9 GET /\n192.168.1.5 GET /exam\n' > access.log cut -d' ' -f1 access.log | sort | uniq -c | sort -rn ls nosuchfile 2> errors.txt; echo "error saved: $(cat errors.txt | cut -c1-30)" echo first > out.txt; echo second >> out.txt; cat out.txt
✅ Verified output
3 192.168.1.5
1 10.0.0.9
1 10.0.0.2
error saved: ls: cannot access 'nosuchfile'
first
second
find and xargs
find searches the tree by name, type, size or age; -exec or xargs runs a command on each result. Always test with echo before deleting.
cd "$(mktemp -d)" mkdir -p a/b c touch a/x.log a/b/y.log c/z.txt a/b/keep.txt find . -name '*.log' | sort find . -type f -name '*.log' -print0 | xargs -0 echo would delete: find . -type d | sort find . -newer a/x.log -type f | sort
✅ Verified output
./a/b/y.log ./a/x.log would delete: ./a/x.log ./a/b/y.log . ./a ./a/b ./c
sed and awk for text processing
sed edits streams (substitute with s/old/new/g); awk splits lines into fields and can compute sums and averages.
printf 'name,dept,salary\nAsha,IT,52000\nRavi,HR,41000\nMeena,IT,61000\n' > /tmp/staff.csv
sed 's/,/ | /g' /tmp/staff.csv
awk -F, 'NR > 1 { total[$2] += $3; n[$2]++ } END { for (d in total) printf "%s average %.0f\n", d, total[d] / n[d] }' /tmp/staff.csv | sort
sed -n '2p' /tmp/staff.csv
✅ Verified output
name | dept | salary Asha | IT | 52000 Ravi | HR | 41000 Meena | IT | 61000 HR average 41000 IT average 56500 Asha,IT,52000
Archives with tar and gzip
tar packs many files into one archive; -z compresses with gzip. c creates, x extracts, t lists, v is verbose, f names the file.
cd "$(mktemp -d)"
mkdir -p site/img && echo '<h1>Hi</h1>' > site/index.html && head -c 2000 /dev/zero > site/img/blank.bin
tar -czf site.tgz site
tar -tzf site.tgz | sort
ls -l site.tgz | awk '{print "archive size:", $5, "bytes"}'
mkdir restore && tar -xzf site.tgz -C restore && ls restore/site
✅ Verified output
site/ site/img/ site/img/blank.bin site/index.html archive size: 210 bytes img index.html
🌳 Advanced (5)
Disk and memory usage
df shows free space per file system, du shows how much a folder uses, free shows memory. -h prints human-friendly sizes.
df -h / | awk 'NR == 1 || NR == 2 { print $1, $2, $5 }'
mkdir -p /tmp/du && head -c 3000000 /dev/zero > /tmp/du/big.bin && head -c 1000 /dev/zero > /tmp/du/small.bin
du -sh /tmp/du
du -ah /tmp/du | sort -h | tail -3
free -h | head -2 | awk '{print $1, $2}'
✅ Verified output
Filesystem Size Use% overlay 1007G 7% 2.9M /tmp/du 4.0K /tmp/du/small.bin 2.9M /tmp/du 2.9M /tmp/du/big.bin total used Mem: 15Gi
Environment variables and PATH
Variables configure programs. export makes a variable visible to child processes. PATH lists the folders searched for commands, in order.
export APP_ENV=production
bash -c 'echo "child sees APP_ENV=$APP_ENV"'
LOCAL_ONLY=1
bash -c 'echo "child sees LOCAL_ONLY=${LOCAL_ONLY:-<unset>}"'
echo "$PATH" | tr ':' '\n' | head -3
command -v ls
✅ Verified output
child sees APP_ENV=production child sees LOCAL_ONLY=<unset> /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin/ls
SSH keys and fingerprints
ssh-keygen makes a key pair: the private key stays on your machine, the public key goes on servers (~/.ssh/authorized_keys). Ed25519 keys are short and strong.
cd "$(mktemp -d)"
ssh-keygen -t ed25519 -N '' -C 'student@gayagnan' -f id_demo -q
ls id_demo*
cut -d' ' -f1,3 id_demo.pub
ssh-keygen -lf id_demo.pub | awk '{print $1, $4}'
stat -c '%a %n' id_demo id_demo.pub
✅ Verified output
id_demo id_demo.pub ssh-ed25519 student@gayagnan 256 (ED25519) 600 id_demo 644 id_demo.pub
Hashes and TLS certificates with openssl
sha256sum proves a file has not changed. openssl can create a self-signed certificate and print its details, as servers use for HTTPS.
cd "$(mktemp -d)" echo "release 1.0" > app.tar sha256sum app.tar | cut -c1-16 openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 30 -subj '/CN=lab.gayagnan.local' 2>/dev/null openssl x509 -in cert.pem -noout -subject -issuer openssl x509 -in cert.pem -noout -checkend 86400 && echo "valid for at least one more day"
✅ Verified output
7b4871e6b3540505 subject=CN=lab.gayagnan.local issuer=CN=lab.gayagnan.local Certificate will not expire valid for at least one more day
Git basics from the command line
git init starts a repository, add stages changes, commit records them, log shows history, branch and merge combine work.
cd "$(mktemp -d)" git init -q -b main && git config user.email s@lab && git config user.name Student echo v1 > notes.txt && git add notes.txt && git commit -qm "first note" git switch -q -c feature && echo v2 >> notes.txt && git commit -qam "add v2" git switch -q main && git merge -q feature git log --oneline | cut -d' ' -f2- cat notes.txt
✅ Verified output
add v2 first note v1 v2
💻 Terminal on my computer
Like a cloud shell, but on your own laptop: install compilers and run real commands from this page through the free GayaGnan agent. It asks you before connecting, installing or running anything.
🛠️ Set up and verify
- Install
wsl --install (Ubuntu on Windows)
use a Linux VM (UTM) or a cloud VM
open a terminal
- Editor: Visual Studio Code with Remote - SSH, Bash IDE.
- Create
check.shecho "Hello, GayaGnan!"; whoami
- Run it and check the version
check.sh uname -a
- Health check: paste what your terminal printed.
Install one language at a time. These commands only install or print versions; nothing here deletes files. Versions change: check the official page and note the version you installed.
🧭 The 14-lab path
- 00 · Setup and verify — install the runtime and editor, run hello world, print the version, fix PATH
- 01 · Syntax and trace — follow each line and the value of every variable
- 02 · Logic — conditionals and decision trees
- 03 · Loops — trace tables and loop challenges
- 04 · Functions — break problems down and test each piece
- 05 · Data structures — lists, maps, stacks, queues and trees you can see
- 06 · Debugging — bug cases with a hint ladder
- 07 · Algorithms — search, sort and Big-O comparison
- 08 · Files and data — read and write fixture files
- 09 · API or database — talk to a mock API or a sandbox database
- 10 · Testing — write tests and read failing assertions
- 11 · Security — secure coding and dependency hygiene for this language
- 12 · Project — one portfolio mini-project
- 13 · Assessment — quiz, coding test, rubric and an explain-your-answer prompt
📚 Modules
- files and folders
- reading files
- permissions
- grep
- users and groups
- ownership
- processes
- pipes
- find
- sed and awk
- archives
- disk and memory
- environment
- SSH keys
- OpenSSL
- git
🏗️ Mini-projects
- Server hardening checklist
- Log report script
- Backup script with tar and cron
Projects use synthetic data only.