Terminal Lab
Learn Linux commands in a real, isolated container environment
Connecting to lab engine...
Checking if real Linux environments are available
Real Container Lab
Launch an ephemeral LXC container for hands-on practice. Auto-destroys after 60 minutes.
Prefer offline mode?
Provisioning a real Linux container on isolated infrastructure
Creating LXC container on Proxmox...
Booting Alpine Linux & installing tools...
Opening live terminal session...
!
Failed to create lab
Connected to live container -- this is a real, isolated Linux environment
Simulation Mode -- Could not reach lab engine. Using client-side sandbox.
Challenges
Learn to move around the filesystem
○ List the files in /etc
- Type ls /etc and press Enter
- You should see a list of system configuration files and directories like hostname, passwd, and shadow
- Try ls -la /etc to see permissions, ownership, sizes, and hidden files
ls /etc 💡 The ls command lists directory contents. Add -l for long format with details, -a to include hidden files (those starting with a dot).
○ Change to the /var/log directory
- Type cd /var/log and press Enter
- Your prompt should change to reflect the new directory — look for /var/log in your path
- Run ls to see what log files live here — this is where Linux keeps its system logs
cd /var/log 💡 The cd command changes your working directory. Think of it as opening a folder. Use cd .. to go back up one level.
○ Print the current working directory
- Type pwd and press Enter
- It should print the full path to wherever you currently are, like /var/log if you just did the previous task
- This is useful when you get lost — pwd always tells you exactly where you are in the filesystem
pwd 💡 pwd stands for "print working directory." It shows your absolute path from the root (/) of the filesystem.
○ List files with full details
- Type ls -la and press Enter from any directory
- Each line shows: permissions, link count, owner, group, size, date, and filename
- Notice entries starting with d are directories, and entries starting with . are hidden files
ls -la 💡 The -l flag gives long format (permissions, sizes, dates). The -a flag shows all files including hidden ones. Together, -la gives you the complete picture.
Expected:
A detailed listing with columns for permissions (like drwxr-xr-x), owner, size, date, and name
○ Navigate to your home directory
- Type cd ~ and press Enter (the tilde character ~ is a shortcut for your home directory)
- Run pwd to confirm you are now in /root (since you are logged in as root on Alpine)
- You can also just type cd with no arguments — it does the same thing
cd ~ 💡 The ~ character is a shell shortcut that always expands to your home directory. For the root user, that is /root. For regular users, it would be /home/username.
Create, view, and manage files
○ Create a file with echo
- Type echo "hello" > hello.txt and press Enter
- The > operator redirects the output of echo into a new file called hello.txt
- Run ls to confirm hello.txt was created in your current directory
echo "hello" > hello.txt 💡 The > operator creates a new file (or overwrites an existing one) with the command output. Use >> instead to append without overwriting.
○ View the file contents
- Type cat hello.txt and press Enter
- You should see the word "hello" printed to the terminal
- cat is short for "concatenate" — it reads files and prints them to stdout
cat hello.txt 💡 cat is the simplest way to view a file. For long files, use less or more to scroll through them page by page.
Expected:
hello
○ Create a new directory
- Type mkdir projects and press Enter
- Run ls to confirm the projects directory was created
- Try cd projects to enter it, then pwd to verify your location
mkdir projects 💡 mkdir stands for "make directory." Add -p to create nested directories in one command, like mkdir -p projects/src/utils.
○ Copy a file into a directory
- Type cp hello.txt projects/ and press Enter
- Run ls projects/ to confirm hello.txt was copied there
- The original file still exists — cp makes a copy, it does not move it
cp hello.txt projects/ 💡 cp copies files and directories. Use cp -r for recursive copying of entire directory trees. The trailing / on projects/ is optional but makes it clear you mean a directory.
○ View the OS release info
- Type cat /etc/os-release and press Enter
- You should see key-value pairs describing the operating system — NAME, VERSION, ID, etc.
- Look for PRETTY_NAME to see the human-readable OS description (should be Alpine Linux)
cat /etc/os-release 💡 The /etc/os-release file is a standard file on modern Linux distros that identifies the OS. It is useful for scripts that need to detect which distro they are running on.
Expected:
NAME="Alpine Linux" along with version and ID fields
Find files and search content like a pro
○ Find all .conf files in /etc
- Type find /etc -name "*.conf" and press Enter
- The find command will recursively search /etc and print every file matching the *.conf pattern
- Try adding -type f to limit results to files only: find /etc -type f -name "*.conf"
find /etc -name "*.conf" 💡 find is one of the most powerful Linux commands. The -name flag matches filenames with glob patterns. Always quote your pattern to prevent the shell from expanding it before find sees it.
○ Search for "root" in /etc/passwd
- Type grep "root" /etc/passwd and press Enter
- grep will print every line in the file that contains the word "root"
- Try grep -n "root" /etc/passwd to also show line numbers, or grep -i "ROOT" /etc/passwd for case-insensitive matching
grep "root" /etc/passwd 💡 grep searches file contents for a pattern and prints matching lines. It supports regular expressions for complex matching. The -i flag makes it case-insensitive, -n adds line numbers, -c counts matches.
Expected:
At least one line showing root:x:0:0:root:/root:/bin/bash (or similar)
○ Locate the bash binary with which
- Type which bash and press Enter
- which searches your PATH and prints the full path to the first matching executable
- Try which ls and which grep to see where other common commands live
which bash 💡 which only searches directories listed in your PATH environment variable. If a program is installed but not in PATH, which will not find it. Use find / -name "bash" as a fallback.
Expected:
/bin/bash or /usr/bin/bash depending on the system
○ Pipe ls output through grep
- Type ls /etc | grep conf and press Enter
- The pipe (|) takes the output of ls and sends it as input to grep, which filters for lines containing "conf"
- This is a fundamental pattern — chaining commands with pipes to build powerful one-liners
ls /etc | grep conf 💡 The pipe operator (|) connects the stdout of one command to the stdin of the next. This lets you chain simple tools together into powerful workflows. You can chain as many pipes as you want.
○ Count lines in a file with wc
- Type wc -l /etc/passwd and press Enter
- wc (word count) with the -l flag counts the number of lines in the file
- Try wc -w /etc/passwd for word count, or just wc /etc/passwd for lines, words, and bytes all at once
wc -l /etc/passwd 💡 wc stands for "word count" but it does more than words. Use -l for lines, -w for words, -c for bytes, -m for characters. It is commonly piped with other commands: cat file | wc -l.
Expected:
A number followed by the filename, like "25 /etc/passwd"
Monitor and control running processes
○ List all running processes
- Type ps aux and press Enter
- You will see a table of every running process with columns for user, PID, CPU%, memory%, and the command
- Look at the PID column — every process gets a unique Process ID number that you can use to control it
ps aux 💡 ps aux shows all processes for all users in a BSD-style format. The a flag shows other users, u gives user-oriented output, x includes processes without a terminal. This is one of the most common Linux debugging commands.
Expected:
A table with columns: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND
○ View real-time process activity
- Type top and press Enter to launch the interactive process monitor
- Watch the display update every few seconds — it shows CPU, memory, and the top resource consumers
- Press q to exit top and return to your shell
top 💡 top is an interactive process viewer. Press M to sort by memory, P to sort by CPU, k to kill a process by PID, and q to quit. On Alpine, htop may also be available (install with apk add htop) for a more user-friendly version.
○ Find a process by name with pgrep
- Type pgrep -a sh and press Enter to find all processes with "sh" in their name
- The -a flag shows the full command line along with the PID
- Try pgrep -l top to see if top is still running, or pgrep -u root to list all processes owned by root
pgrep -a sh 💡 pgrep searches for processes by name pattern. It is cleaner than ps aux | grep something because it does not match itself in the results. Use -l for name, -a for full command, -u for user filter.
○ Run a background process
- Type sleep 60 & and press Enter — the & sends the process to the background
- You will see output like [1] 1234 — the number in brackets is the job number, and 1234 is the PID
- Type jobs to see your background jobs, and note the PID for the next task
sleep 60 & 💡 Adding & after any command runs it in the background so you can keep using the terminal. sleep 60 just waits for 60 seconds and does nothing — it is perfect for practicing process management.
Expected:
Something like [1] 1234 where 1234 is the process ID
○ Kill the background process
- Type kill followed by the PID from the previous step, like kill 1234
- Press Enter, then run jobs again to confirm the process was terminated
- If a process refuses to die, use kill -9 PID to force-kill it (SIGKILL instead of SIGTERM)
kill %1 💡 kill sends a signal to a process. By default it sends SIGTERM (signal 15), which asks the process to shut down gracefully. kill -9 sends SIGKILL which forces immediate termination. You can use %1 to reference job number 1 instead of the PID.
Understand Linux file permissions and ownership
○ View file permissions
- Type ls -la /etc/passwd and press Enter
- Look at the first column — something like -rw-r--r-- which breaks down as: file type, owner permissions, group permissions, other permissions
- r = read, w = write, x = execute. So rw-r--r-- means the owner can read and write, everyone else can only read
ls -la /etc/passwd 💡 Permission strings are 10 characters: the first is the type (- for file, d for directory, l for link), then three triplets of rwx for owner, group, and others. A dash means that permission is not granted.
Expected:
-rw-r--r-- 1 root root ... /etc/passwd
○ Create an executable script with chmod
- First, create a script: echo '#!/bin/sh echo "it works"' > myscript.sh
- Check its permissions with ls -la myscript.sh — notice there is no x (execute) permission
- Type chmod +x myscript.sh to add execute permission, then run it with ./myscript.sh
chmod +x myscript.sh 💡 chmod changes file permissions. The +x shorthand adds execute permission for all users. You can be more specific: chmod u+x for owner only, chmod 755 for rwxr-xr-x using octal notation.
○ Check your current user identity
- Type whoami and press Enter — it prints your username
- Now type id and press Enter — this shows your user ID (uid), group ID (gid), and all groups you belong to
- On this container, you should be root with uid=0, which means full system access
whoami && id 💡 whoami shows just the username. id shows the full picture: numeric user ID, primary group, and all supplementary groups. Root always has uid=0 and gid=0.
Expected:
root followed by uid=0(root) gid=0(root) groups=0(root)...
○ Check who is logged in
- Type w and press Enter to see who is currently logged into the system
- The output shows each logged-in user, their terminal, login time, and what command they are running
- On a container you may only see your own session — on a shared server you would see everyone
w 💡 The w command is a quick way to see system load and who is doing what. It combines info from uptime and who into one view. The header line shows current time, uptime, and load averages.
○ Examine /etc/passwd entries
- Type cat /etc/passwd and press Enter
- Each line is a user account in the format: username:x:uid:gid:description:home:shell
- Look for root (uid 0) and nobody (often uid 65534). The x in the password field means the actual hash is in /etc/shadow
cat /etc/passwd 💡 Despite its name, /etc/passwd no longer stores passwords. Each colon-separated field has meaning: username, password placeholder (x), user ID, group ID, comment/full name, home directory, login shell. Users with /sbin/nologin as their shell cannot log in interactively.
Write and execute bash scripts
○ Write a script that prints a greeting
- Type cat > greet.sh << 'EOF' #!/bin/sh echo "Hello from the lab!" EOF
- This uses a heredoc to write multiple lines into a file — the script starts with #!/bin/sh (the shebang) which tells Linux which interpreter to use
- Verify the contents with cat greet.sh
cat > greet.sh << 'EOF'
#!/bin/sh
echo "Hello from the lab!"
EOF 💡 Every shell script should start with a shebang line (#!/bin/sh or #!/bin/bash). This tells the OS which interpreter to use. On Alpine, /bin/sh is typically BusyBox ash, which is POSIX-compliant but lacks some bash-specific features.
○ Make the script executable and run it
- Type chmod +x greet.sh to add execute permission
- Run it with ./greet.sh — the ./ prefix tells the shell to look in the current directory
- You should see "Hello from the lab!" printed to the terminal
chmod +x greet.sh && ./greet.sh 💡 You need ./ because the current directory is usually not in your PATH for security reasons. Without it, the shell looks only in PATH directories like /usr/bin. Alternatively, you can run it with sh greet.sh without making it executable.
Expected:
Hello from the lab!
○ Write a for loop to create numbered files
- Type: for i in 1 2 3 4 5; do touch "file_$i.txt"; done
- This loops through the numbers 1-5 and creates a file for each one using touch
- Run ls file_*.txt to see all five files: file_1.txt through file_5.txt
for i in 1 2 3 4 5; do touch "file_$i.txt"; done 💡 for loops iterate over a list of values. In bash you can also use: for i in $(seq 1 5) or for i in {1..5}. The $i variable holds the current value on each iteration. The semicolons separate the do and done keywords when writing on one line.
○ Write a script with if/else logic
- Create the script: cat > check.sh << 'EOF' #!/bin/sh if [ -f /etc/hostname ]; then echo "Hostname file exists: $(cat /etc/hostname)" else echo "No hostname file found" fi EOF
- Make it executable and run it: chmod +x check.sh && ./check.sh
- The -f test checks if a file exists — try changing it to a file that does not exist to see the else branch
chmod +x check.sh && ./check.sh 💡 if/else in shell scripts uses [ ] (test) for conditions. Common file tests: -f (file exists), -d (directory exists), -r (readable), -w (writable), -x (executable). String comparisons use = and !=. Numeric comparisons use -eq, -ne, -lt, -gt.
○ Use command substitution with $()
- Type echo "Today is $(date)" and press Enter
- The $() syntax runs the command inside it and substitutes the output into the string
- Try combining them: echo "You are $(whoami) on $(hostname) at $(date +%H:%M)"
echo "Today is $(date)" 💡 Command substitution $() runs a command and replaces itself with the output. It can be nested: echo "Files: $(ls $(pwd))". The older backtick syntax `command` works too but $() is preferred because it nests cleanly.
Expected:
Today is [current date and time]
Chain commands together for powerful workflows
○ Redirect command output to a file
- Type ls /etc > listing.txt and press Enter
- The > operator captures the stdout of ls and writes it to listing.txt instead of the screen
- Verify with cat listing.txt — you should see the contents of /etc saved in the file
ls /etc > listing.txt 💡 The > operator creates the file if it does not exist or overwrites it if it does. Be careful — it silently destroys existing content. Use >> to append instead. Redirect stderr with 2> and both with &>.
○ Append to an existing file
- Type echo "--- end of listing ---" >> listing.txt and press Enter
- The >> operator appends to the file instead of overwriting it
- Run cat listing.txt and scroll to the bottom — you should see your appended line after the directory listing
echo "--- end of listing ---" >> listing.txt 💡 The difference between > and >> is critical. > overwrites (destructive), >> appends (safe). A common pattern is using >> to build up log files: echo "$(date): event happened" >> app.log
○ Chain multiple commands with pipes
- Type cat /etc/passwd | grep root | wc -l and press Enter
- This reads the passwd file, filters for lines containing "root," then counts how many lines matched
- Each pipe passes the output of one command as input to the next — you can chain as many as you need
cat /etc/passwd | grep root | wc -l 💡 This is the Unix philosophy in action: small tools that each do one thing well, chained together with pipes to solve complex problems. cat reads, grep filters, wc counts. Each tool is simple but together they are powerful.
Expected:
A number (usually 1 or 2) representing lines containing "root"
○ Use tee to split output to file and screen
- Type ls /etc | tee etc_files.txt and press Enter
- You will see the listing printed to the screen AND saved to etc_files.txt at the same time
- Verify with cat etc_files.txt — tee is like a T-junction in plumbing, splitting the stream two ways
ls /etc | tee etc_files.txt 💡 tee is invaluable for debugging pipelines — you can see the data flowing through while also saving it. Use tee -a to append instead of overwrite. You can tee to multiple files: command | tee file1.txt file2.txt.
○ Sort a file and remove duplicates
- First create a file with duplicates: printf "banana\napple\ncherry\napple\nbanana\ndate\n" > fruits.txt
- Type sort -u fruits.txt and press Enter to sort alphabetically and remove duplicate lines
- Compare with just sort fruits.txt (duplicates kept) and sort fruits.txt | uniq (only removes adjacent duplicates — that is why sort comes first)
sort -u fruits.txt 💡 sort -u combines sorting and deduplication in one step. The separate uniq command only removes consecutive duplicates, so it must be paired with sort. For counting occurrences, use sort | uniq -c to get a count of each unique line.
Expected:
apple, banana, cherry, date — sorted alphabetically with no duplicates
Explore services and scheduled tasks
○ List running services
- Type rc-status and press Enter (Alpine uses OpenRC, not systemd)
- You will see services grouped by runlevel — look for started and stopped services
- If rc-status is not available, try service --status-all or ls /etc/init.d/ to see available service scripts
rc-status 💡 Alpine Linux uses OpenRC as its init system. rc-status shows all services and their current state. On systemd distros you would use systemctl list-units instead. Understanding your init system is key to managing services.
○ Explore the init.d service directory
- Type ls -la /etc/init.d/ and press Enter
- Each file here is a service script that can be started, stopped, or restarted
- Try cat /etc/init.d/hostname to see what a simple service script looks like — notice the start() and stop() functions
ls -la /etc/init.d/ 💡 The /etc/init.d/ directory contains service scripts that control daemons and system services. These are shell scripts with standard functions (start, stop, restart, status). You run them via rc-service or directly: /etc/init.d/servicename start.
○ View the crontab format
- Type crontab -l to see the current user crontab (may be empty)
- If that is empty, try cat /etc/crontabs/root or ls /etc/cron*/ to see system cron configuration
- The format is: minute hour day month weekday command — for example, 0 * * * * means "every hour on the hour"
crontab -l 💡 Cron schedules recurring tasks. The five time fields are: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-7, where 0 and 7 are Sunday). An asterisk * means "every." You can install crond on Alpine with: apk add dcron && rc-service dcron start.
○ Set up a cron job that logs the date
- Make sure crond is running: apk add dcron 2>/dev/null; rc-service dcron start 2>/dev/null; crond 2>/dev/null
- Type: echo "* * * * * date >> /tmp/cronlog.txt" | crontab -
- Wait about 60 seconds, then check: cat /tmp/cronlog.txt — you should see timestamps appearing every minute
echo "* * * * * date >> /tmp/cronlog.txt" | crontab - 💡 The crontab - command reads cron entries from stdin. Using * * * * * means every minute — great for testing but do not leave it running in production. Remove it with crontab -r when done. Always redirect output in cron jobs or it will try to mail it.
○ Run a command that survives logout with nohup
- Type nohup sh -c "while true; do date >> /tmp/nohup_test.txt; sleep 5; done" &
- nohup prevents the process from being killed when you close the terminal, and & runs it in the background
- Check it is running with jobs or ps aux | grep nohup_test, then verify output with cat /tmp/nohup_test.txt
nohup sh -c "while true; do date >> /tmp/nohup_test.txt; sleep 5; done" & 💡 nohup stands for "no hangup" — it prevents the SIGHUP signal (sent when a terminal closes) from killing the process. Output goes to nohup.out by default unless redirected. Combined with &, it creates a simple background daemon. Clean up with: kill $(pgrep -f nohup_test)
Deep-dive into system internals
○ Inspect CPU and memory info from /proc
- Type cat /proc/cpuinfo and press Enter to see detailed CPU information — model, cores, clock speed, flags
- Type cat /proc/meminfo and press Enter to see memory stats — total, free, available, buffers, cached
- Try head -5 /proc/cpuinfo to see just the first few lines, or grep "model name" /proc/cpuinfo for a quick summary
cat /proc/cpuinfo && echo "---" && cat /proc/meminfo 💡 The /proc filesystem is a virtual filesystem that exposes kernel and process data as files. /proc/cpuinfo and /proc/meminfo are read directly from kernel data structures — they are not real files on disk. This is how tools like top and htop get their information.
○ Monitor disk I/O statistics
- Type cat /proc/diskstats and press Enter to see raw disk I/O counters for every block device
- If iostat is available (install with apk add sysstat), run iostat -x 1 3 for extended stats every second, 3 times
- The key columns to watch are: reads/writes completed, time spent on I/O, and I/O queue depth
cat /proc/diskstats 💡 /proc/diskstats shows cumulative I/O counters since boot. The columns include reads completed, reads merged, sectors read, milliseconds reading, and the same for writes. iostat makes this human-readable. High I/O wait (wa% in top) often indicates disk bottlenecks.
○ Trace system calls with strace
- Install strace if needed: apk add strace
- Type strace ls /tmp 2>&1 | head -30 and press Enter — this traces every system call that ls makes
- You will see calls like openat(), read(), write(), close() — these are the low-level operations the kernel performs on behalf of the program
strace ls /tmp 2>&1 | head -30 💡 strace intercepts and logs every system call a program makes. It is invaluable for debugging why a program is failing — you can see exactly which file it tried to open, what network call it made, or where it got a permission denied. Use -e trace=open to filter for specific calls.
Expected:
Lines like execve(), openat(), read(), write() showing the syscalls ls makes
○ Examine open file descriptors
- Type ls -la /proc/self/fd and press Enter — /proc/self always refers to the current process
- You will see file descriptors 0 (stdin), 1 (stdout), 2 (stderr), and possibly more
- Try ls -la /proc/1/fd to see what file descriptors PID 1 (the init process) has open
ls -la /proc/self/fd 💡 Every process has file descriptors: 0=stdin, 1=stdout, 2=stderr. Additional FDs are opened for files, sockets, pipes, etc. /proc/PID/fd shows them as symlinks to the actual files. This is extremely useful for debugging "too many open files" errors or finding what files a process is using.
Expected:
Symlinks for fd 0, 1, 2 pointing to /dev/pts/* or pipes
○ Profile a command with time
- Type time find / -name "*.conf" 2>/dev/null and press Enter
- When it finishes, you will see three timing values: real (wall clock), user (CPU in user mode), sys (CPU in kernel mode)
- If real is much larger than user+sys, the process spent most of its time waiting (for disk, network, etc.)
time find / -name "*.conf" 2>/dev/null 💡 The time command measures execution duration. "real" is total elapsed time, "user" is CPU time in user space, "sys" is CPU time in kernel space. If real >> user+sys, the bottleneck is I/O. If user is high, the bottleneck is CPU. This is a quick way to understand where a command spends its time.
Expected:
A list of .conf files followed by real/user/sys timing breakdown
Network configuration and diagnostics from the terminal
○ View network interfaces
- Type ip addr and press Enter (or ip a for short)
- You will see each network interface: lo (loopback at 127.0.0.1) and eth0 (or similar) with its assigned IP address
- Look for the inet line under eth0 — that is your container IP address and subnet mask in CIDR notation
ip addr 💡 ip addr (or ip a) is the modern replacement for ifconfig. Each interface shows: state (UP/DOWN), MAC address (link/ether), IPv4 address (inet), and IPv6 address (inet6). The /24 after an IP means a 255.255.255.0 subnet mask (254 usable hosts).
Expected:
lo with 127.0.0.1/8 and eth0 with an IP like 10.x.x.x/24 or 172.x.x.x/16
○ Check the routing table
- Type ip route and press Enter (or ip r for short)
- The "default via" line shows your gateway — that is where traffic goes when it is not destined for the local network
- Other lines show directly connected subnets — traffic to those IPs stays on the local network without going through the gateway
ip route 💡 The routing table tells the kernel where to send packets. "default via X" means all unknown destinations go to gateway X. Directly connected routes (like 10.42.0.0/24 dev eth0) are for the local subnet. Understanding routing is essential for debugging connectivity issues.
Expected:
A default route via a gateway IP and one or more local subnet routes
○ Test DNS resolution
- Type nslookup google.com and press Enter (or dig google.com if available)
- You will see which DNS server was queried and the IP address(es) returned for the domain
- If neither tool is available, install with: apk add bind-tools (for dig) or apk add busybox-extras (for nslookup)
nslookup google.com 💡 DNS translates domain names to IP addresses. nslookup and dig query DNS servers directly. Check /etc/resolv.conf to see which DNS servers your system is configured to use. If DNS is not working, you can still reach hosts by IP address — that is a key troubleshooting distinction.
Expected:
The DNS server used and one or more IP addresses for google.com
○ Download a file from the internet
- Type wget -O /tmp/test.html https://example.com and press Enter to download a web page
- You will see a progress bar showing the download — the -O flag specifies the output filename
- Verify with cat /tmp/test.html or use curl https://example.com for a simpler output directly to stdout
wget -O /tmp/test.html https://example.com 💡 wget and curl are both HTTP clients but with different defaults. wget saves to a file by default and supports recursive downloads. curl prints to stdout by default and supports more protocols. Both are essential tools for scripting and debugging web services.
Expected:
A download progress indicator followed by "saved" confirmation
○ Examine open network ports
- Type ss -tlnp and press Enter to see all listening TCP ports
- Each line shows: state (LISTEN), local address:port, and the process holding the port open
- The flags mean: -t TCP only, -l listening sockets only, -n numeric (don't resolve names), -p show process info
ss -tlnp 💡 ss (socket statistics) is the modern replacement for netstat. Use -t for TCP, -u for UDP, -l for listening, -n for numeric output, -p for process info. This is your go-to command for "what is listening on what port" questions. Add -a to see all sockets including established connections.
Expected:
A table showing State, Recv-Q, Send-Q, Local Address:Port, Peer Address:Port, and process info
What You Can Do
- Full root access to Alpine Linux container
- Install packages with apk (Alpine package manager)
- Create files, scripts, and directories
- Manage processes, users, and permissions
- Network tools: ping, curl, wget, dig, ss
- Text editors: vi, nano (install with apk add nano)
Learning Objectives
Beginner
- Navigate the filesystem
- Create and manage files
- View system information
Intermediate
- Manage processes
- Understand permissions
- Use piping and grep
Advanced
- Write shell scripts
- Configure services
- Chain complex commands
Expert
- Analyze performance
- Explore /proc filesystem
- Build and compile software
Quick Reference
lsList directory contentscd <dir>Change directorycat <file>View file contentspwdPrint working directoryfindSearch for filesgrepSearch file contents LIVE Connecting...
Session
--- Time Left --:--
CPU 0%
MEM 0%
visitor@argobox-sandbox ~ bash (simulation)
_ ____
/ \ _ __ __ _ ___ | __ ) _____ __
/ _ \ | '__/ _` |/ _ \| _ \ / _ \ \/ /
/ ___ \| | | (_| | (_) | |_) | (_) > <
/_/ \_\_| \__, |\___/|____/ \___/_/\_\
|___/
Welcome to the ArgoBox Terminal Sandbox! (Simulation Mode)
Type help for available commands or try a challenge from the sidebar.
visitor@argobox:~$
Pro Tips
⬆️ Use Up Arrow to recall previous commands
⇥ Press Tab for command auto-completion
🔍 Use
man <cmd> for command documentation 📋 Commands are case-sensitive in Linux