👑 Premium Sign in Sign up

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.

💻 Runs on your computerOfficial download & docs ↗

📖 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

  1. Install
    wsl --install   (Ubuntu on Windows)
    use a Linux VM (UTM) or a cloud VM
    open a terminal
  2. Editor: Visual Studio Code with Remote - SSH, Bash IDE.
  3. Create check.sh
    echo "Hello, GayaGnan!"; whoami
  4. Run it and check the version
    check.sh
    uname -a
  5. 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

  1. files and folders
  2. reading files
  3. permissions
  4. grep
  5. users and groups
  6. ownership
  7. processes
  8. pipes
  9. find
  10. sed and awk
  11. archives
  12. disk and memory
  13. environment
  14. SSH keys
  15. OpenSSL
  16. git

🏗️ Mini-projects

  • Server hardening checklist
  • Log report script
  • Backup script with tar and cron

Projects use synthetic data only.