Master Linux Admin For DevOps & SRE - Lecture-by-Lecture Command Cheat Sheet
Master Linux Admin For DevOps & SRE - Lecture-by-Lecture Command Cheat Sheet
No new commands introduced in this introductory lecture. It provides an overview of Linux’s importance in
DevOps/SRE and how the course is structured.
This lecture guides you through preparing a Linux environment (installing Ubuntu on a VM or cloud
instance). It may not introduce specific Linux commands beyond verifying the system: - uname -a –
Displays system information including the kernel name, version, and architecture. For example,
uname -a might output the Linux kernel version and Ubuntu details (useful to confirm you’re on the
correct OS).
- lsb_release -a – Shows the Linux distribution information (e.g., Ubuntu release version). This
helps verify that Ubuntu is installed and identify the version (e.g., Ubuntu 20.04 or 22.04).
Introduces the Linux shell (bash) and basic command structure: - echo "Hello, world!" – Prints
text to the terminal. In this demo, it outputs Hello, world! to show how a simple command works.
- whoami – Displays the current user’s username. This confirms your user identity (e.g., it will output
ubuntu or root depending on which user you are).
- man <command> – Opens the manual page for a command. For example, man ls shows the
manual (help documentation) for the ls command. (This lecture likely demonstrated accessing help;
pressing q quits the manual page.)
This lecture covers moving around the filesystem: - pwd – “Print Working Directory,” shows the full
path of the current directory you’re in. E.g., running pwd might output /home/ubuntu indicating you
are in the home directory.
- ls – Lists files and directories in the current directory. By default, ls outputs names of items in a
column or row format.
- cd <directory> – Changes the current directory. For example, cd /etc moves you into the /
1
etc directory. Using cd .. goes up one level (to the parent directory), and cd ~ or just cd
returns to your home directory.
Explores useful options for the ls command to get more information: - ls -l – Lists files in long
format, showing details like permissions, owner, size, and modification date. For example, ls -l /
home might output something like:
Here, the first column ( drwxr-xr-x ) shows file type and permissions, the owner and group ( ubuntu
ubuntu ), file size (in bytes), date, and name.
- ls -a – Lists all files, including hidden dotfiles (files beginning with . ). For example, ls -a in a
home directory will show entries like .bashrc (which are hidden by default).
- ls -h – Used with -l as ls -lh , shows sizes in human-readable units (KB, MB, etc.). E.g., a
4096-byte directory might display as 4.0K .
(Real-world use case: combine flags, e.g. ls -alh , to see a detailed, human-readable listing of all files
including hidden ones.)
Shows how to make new directories: - mkdir <dirname> – Creates a directory with the specified
name in the current location. For example, mkdir project will create a new folder named “project”.
Running ls afterward will show the new directory.
- mkdir -p <parent/child> – Creates nested directories in one go (the -p flag creates parent
directories as needed). E.g., mkdir -p dir1/dir2 will create dir1 (if it doesn’t exist) and inside it
create dir2 . This is useful for creating a deep folder structure in one command.
Demonstrates how to delete directories: - rmdir <dirname> – Removes an empty directory. For
example, rmdir testfolder will delete testfolder if it has no files inside. If the directory isn’t
empty, rmdir will complain and not remove it.
- rm -r <dirname> – Recursively removes a directory and its contents. This is used for non-empty
directories. For instance, rm -r project will delete the project directory and all files and
subdirectories under it. (Be cautious: this command permanently deletes files. In real-world use, double-
check the path before pressing Enter.)
- rm -rf <dirname> – Combines recursive removal with force ( -f disables confirmation prompts
or warnings). For example, rm -rf /tmp/oldlogs will force-delete the oldlogs directory and
everything in it without prompting. Use -rf with extreme care, as it won’t ask for confirmation.
Covers simple ways to create files and use output redirection: - touch <filename> – Creates an
empty file if it doesn’t exist, or updates the timestamp on an existing file. For example, touch
notes.txt will create a new empty file named notes.txt . After running this, ls -l notes.txt
shows a file with size 0 bytes.
2
- Output Redirection ( > ) – Sends command output into a file (overwriting the file). For instance,
echo "Hello" > greeting.txt creates greeting.txt containing the text “Hello”. If
greeting.txt existed, this overwrites its content with “Hello”.
- Append Redirection ( >> ) – Appends output to the end of an existing file. E.g., echo "World" >>
greeting.txt would add “World” on a new line at the end of greeting.txt (preserving existing
content).
- cat > <filename> – Another way to create a file by typing content. For example, running cat >
todo.txt allows you to type lines (ending with Ctrl+D ). Those lines become the content of
todo.txt . This uses the cat command (concatenate) reading from standard input and redirecting
to a file.
Teaches how to display and read file content in various ways: - cat <file> – Outputs the entire
contents of a file to the terminal. For a small text file (e.g., cat /etc/hostname ), cat will print its
content immediately. It’s simple but for long files will scroll off the screen.
- less <file> – Opens a file in a scrollable viewer. Use the up/down arrow keys or PgUp/PgDn to
navigate, and press q to quit. For example, less /etc/services lets you scroll through a long file
page by page, which is practical for viewing large configuration files.
- head -n <N> <file> – Shows the first N lines of a file. head -n 5 error.log will display the
first 5 lines of error.log . (If -n isn’t provided, it defaults to 10 lines.)
- tail -n <N> <file> – Shows the last N lines of a file. tail -n 5 error.log prints the final 5
lines. This is useful for seeing the most recent entries in a log file.
- tail -f <file> – “Follow” a file’s end. It continuously displays new lines as they are added to the
file. For instance, tail -f /var/log/syslog will output new log entries in real time, which is
invaluable for monitoring logs as a service runs. (Press Ctrl+C to stop following.)
Explains how to copy and rename/move files and directories: - cp <source> <destination> –
Copies a file. For example, cp notes.txt notes_backup.txt creates a duplicate of notes.txt
named notes_backup.txt . After running this, ls -l would show both files.
- cp -r <directory> <dest_dir> – Recursively copies an entire directory and its contents. E.g.,
cp -r project project_backup makes a full copy of the project folder (with all subfiles and
subfolders) into a new folder named project_backup .
- mv <source> <destination> – Moves or renames a file or directory. If the destination is a
filename, this effectively renames the file. For example, mv notes.txt ideas.txt renames the file
to ideas.txt . If the destination is an existing directory, the source file will be moved into that
directory. For instance, mv ideas.txt Archive/ moves the file into the Archive folder.
(Real-world note: mv is also used for quickly renaming multiple files or organizing files into directories.)
Focuses on removing files safely: - rm <file> – Removes (deletes) a file. For example, rm
ideas.txt will delete the ideas.txt file. Once removed, the file is gone (no recycle bin in Linux
CLI), so be careful.
- rm -i <file> – Interactive remove. This prompts you for confirmation before each deletion. E.g.,
rm -i *.txt would ask you “remove filename.txt? (y/n)” for each matched file. This is a safety net to
prevent accidental deletion of multiple files.
- rm *.<extension> – Using wildcards to remove multiple files. For instance, rm *.log deletes all
3
files ending in .log in the current directory. (In the course, they likely emphasized caution with
wildcards and possibly recommended pairing with -i to confirm each file.)
Introduces the find command to locate files and directories: - find <path> -name "<pattern>"
– Searches for files/directories under the specified path that match the given name pattern. For
example, find /var/log -name "*.log" will look in /var/log and all subfolders for files ending
with .log . A typical output might be:
/var/log/syslog
/var/log/apache2/error.log
/var/log/apache2/access.log
Covers searching text within file contents using grep : - grep "<text>" <file> – Searches for
lines containing the specified text in a file. For example, grep "ERROR" /var/log/syslog will print
all lines in the system log that contain the word “ERROR”. Each matching line is output in full, allowing
you to see context.
- grep -i "<text>" <file> – Case-insensitive search. grep -i "warning" app.log finds
“warning” or “Warning” etc., ignoring case differences.
- grep -R "<text>" <directory> – Recursively search through all files under a directory. For
instance, grep -R "database" /etc will search all files under /etc for the word “database”,
outputting filenames and matching lines. This is useful to find configuration entries across many files.
- grep -n "<text>" <file> – Displays matched lines with line numbers. If you run grep -n
"main" source.c , it might output 42: int main() indicating that "main" was found on line 42,
which is helpful for locating occurrences in code or config files.
Introduces the pipeline mechanism to chain commands: - Pipes ( | ) – The pipe operator sends the
output of one command as input to another. For example, ls -l /etc | grep ".conf" takes the
detailed list of /etc and then filters it to show only lines containing “.conf” (perhaps to list
configuration files). Only matching filenames (with “.conf”) will be output.
- Example: ps aux | grep nginx – Here, ps aux lists all running processes, and the pipe passes
that list to grep nginx to filter and show only lines related to the “nginx” process. This way you can
quickly find if nginx is running and see its process details.
- Chaining multiple pipes: You can use several pipes in one command. E.g.,
cat access.log | grep 404 | wc -l would take a web server log, filter lines with “404” (HTTP
4
404 errors), then count them with wc -l . The final output is just the number of 404 errors found in
the log. (This demonstrates how powerful combining commands can be for quick analyses.)
This lecture shows how to manipulate text output further: - sort – Sorts lines of text alphabetically or
numerically. For example, sort names.txt will output the lines of names.txt in alphabetical order.
You can combine it with other commands via pipes (e.g., grep "ERROR" syslog | sort ).
- Common option: sort -n for numerical sort (e.g., sorting file sizes or numbers) and sort -r for
reverse order.
- uniq – Removes duplicate consecutive lines (often used after sort ). For instance, sort
names.txt | uniq will list unique names in the file (since sorting groups identical lines together,
uniq then strips out duplicates).
- uniq -c : prefix each unique line with a count of how many times it appeared. e.g.
sort names.txt | uniq -c might output:
3 Alice
5 Bob
2 Carol
Introduces Linux file permissions (read, write, execute) and how to interpret them: - Understanding
ls -l output: The leftmost column from ls -l shows permissions. For example:
Breaking down -rw-r--r-- : - The first character ( - ) indicates the type (here a normal file, d would
mean directory). - Then three sets of three characters: rw- are owner’s permissions (read, write, no
execute), r-- are group’s permissions (read only), and r-- are others’ permissions (read only).
- chmod Concept (no command run yet) – They likely explain that chmod will be used to change
these bits. For now, the lecture probably focuses on reading the current permissions and understanding
roles: - Owner (user who owns the file), group, and others (everyone else).
- Permission values: read ( r ), write ( w ), execute ( x ) and how they are represented (or a - if
missing).
(Use case: Before changing permissions, you must understand what the current permissions are and who can
access the file. ls -l is the primary tool to view this.)
5
Lecture 17: Changing Permissions with chmod
Shows how to modify file/directory permissions: - chmod u+x <file> – Adds execute permission for
the user (owner) of the file. For example, if you have a script backup.sh that currently is -rw-r--
r-- , running chmod u+x backup.sh will change it to -rwxr--r-- , making it executable by you
(the owner).
- chmod g-w <file> – Removes write permission from the group. If a file had group write ( rw- for
group), this command would change that to r-- for group.
- chmod o= <file> – Removes all permissions for others (set others’ permissions to none). This is a
quick way to completely restrict a file from public access.
- Numeric mode: chmod 750 <file> – Sets permissions using octal numbers. Here 750 translates
to owner=7 (rwx), group=5 (r-x), others=0 (---). So chmod 750 script.sh makes it readable, writable,
and executable by the owner; readable and executable by group; inaccessible to others.
- Typical outputs: Running ls -l after a chmod lets you verify the change. E.g., before:
-rw-r--r-- , after chmod 750 file you’d see -rwxr-x--- .
(Real-world tip: Common permission sets like 644 for files (rw-r--r--) and 755 for directories/executables (rwxr-
xr-x) were probably mentioned.)
Covers how to change which user or group owns a file: - chown <new_owner> <file> – Changes the
owner of the file. For example, sudo chown root secure.txt would transfer ownership of
secure.txt to the user “root”. Only root (or using sudo) can change file ownership. After this,
ls -l secure.txt will show root as the owner.
- chown <owner>:<new_group> <file> – Changes the owner and group at once. E.g.,
sudo chown ubuntu:developers project sets the file’s owner to “ubuntu” and group to
“developers”. In the ls -l output, you’ll see the second field (group) has changed to developers.
- chgrp <new_group> <file> – Changes just the group ownership of the file (alternative to using
chown owner:newgroup ). For example, sudo chgrp www-data website.html will make “www-
data” the group owner of website.html . Use ls -l to verify (group field changes).
- chmod with group/owner context: They might highlight that changing group or owner doesn’t by
itself alter permissions, but combined with proper chmod settings, you can allow group members to
edit files, etc.
(Real-world use: Ensuring files are owned by the correct user/group is important. For instance, web files owned
by www-data allow the webserver (which runs as www-data ) to access them. The course likely gave such
examples.)
Explains privilege escalation with sudo and managing superuser access: - sudo <command> – Runs
a single command with superuser (root) privileges. For instance, sudo apt update (covered later in
package management) uses sudo because updating the system requires admin rights. When you prefix
any command with sudo, you may be prompted for your password, and then the command executes as
root.
- sudo -i – Opens an interactive root shell. This effectively logs you in as root in the terminal (prompt
changes to # ). You have full privileges until you exit. This was likely mentioned with caution: use it
sparingly.
- visudo – Opens the sudoers configuration in a safe editor. The course may have demonstrated how
to add a user to the sudoers file or, more commonly on Ubuntu, explained that adding a user to the
“sudo” group ( sudo usermod -aG sudo <username> ) grants sudo privileges. The visudo
6
command ensures syntax is correct when editing /etc/sudoers.
- sudo su – An older style (or on other distros) to become root, by running the su (substitute user)
command as sudo. sudo su effectively does the same as sudo -i (gives a root shell).
(Real-world note: On Ubuntu, the first user is usually already in the sudo group. The lecture likely emphasized
using sudo before commands that require root rights, and not logging in as root permanently for safety.)
Focuses on user account creation and management: - sudo adduser <username> – Creates a new
user with a home directory and prompts for a password and user details. For example,
sudo adduser alice will interactively set up a new user “alice”, create /home/alice , and ask for a
password. After running, you’ll see a series of prompts (Full Name, etc., which you can skip or fill).
- sudo userdel <username> – Deletes a user account. E.g., sudo userdel alice will remove
user “alice” (though on Ubuntu, you might use deluser alice , which is essentially the same). Often
you’d add --remove-home to also delete their home directory if desired.
- passwd <username> – Changes the password for a user. If run as a normal user on yourself (just
passwd ), it asks to enter a new password for your account. As root or with sudo, sudo passwd bob
lets you set or reset the password for user “bob”. The system will prompt for the new password (and
confirmation) and update it.
- id <username> – Displays a user’s UID, GID, and group memberships. For example, id alice
might output uid=1002(alice) gid=1002(alice) groups=1002(alice),27(sudo) indicating
alice’s user and group IDs and that she’s in the sudo group. This is useful to verify a new user’s group
memberships.
(In practice, creating users and setting passwords is a common sysadmin task. The course likely stressed
creating a non-root user for daily use and only using sudo when needed.)
Covers creating groups and adding users to groups: - sudo groupadd <groupname> – Creates a new
user group. For example, sudo groupadd developers will create a group named “developers”. You
can verify by checking /etc/group or using getent group developers .
- sudo usermod -aG <group> <username> – Adds an existing user to an existing group. The -aG
flags mean “append to Group”. For instance, sudo usermod -aG developers alice will add user
“alice” to the “developers” group without removing her from any other groups. (The -a is crucial;
without it, the user’s other group memberships would be overwritten.)
- groups <username> – Lists the groups that a user belongs to. E.g., groups alice might output
alice : alice sudo developers , confirming that “alice” is in groups alice (her primary group),
sudo, and developers. If you run groups with no username, it shows your own groups.
- sudo delgroup <groupname> – Deletes a group. For example, sudo delgroup developers
would remove the “developers” group (provided no critical system accounts rely on it). This might be
mentioned for completeness, though adding groups is more common than deleting in a course context.
(Real-world: managing groups is important for setting up permissions – e.g., giving a “developers” group
access to certain files or directories. The lecture likely demonstrated adding a user to the sudo group with
usermod -aG sudo username as a concrete example.)
Shows how to see who is using the system: - who – Lists currently logged-in users and their terminals.
It might output something like:
7
alice pts/0 2025-05-19 13:45 (192.168.1.100)
indicating user “alice” is logged in on terminal pts/0 since that date/time, possibly with the remote IP.
- w – Provides a more detailed view of logged-in users and their activity. It shows who is logged in and
what command they are running. For example, w might output an entry:
This shows system uptime, number of users, and then each user’s session info including what
command (“WHAT”) they’re doing (here alice is at a bash shell).
- last – Displays the history of user logins (from /var/log/wtmp ). For instance, last might list:
This tells you when users logged in and out. “still logged in” means the session is current. This is useful
for auditing logins or seeing the last reboot time.
- lastb – (May be mentioned) similar to last but shows failed login attempts (from /var/log/
btmp ). Requires sudo usually: sudo lastb would show if someone tried wrong passwords, etc.
(Such commands are helpful for monitoring multi-user systems or just checking if you have active SSH
sessions open.)
Introduces environment variables and how to set them: - env – Displays all the current environment
variables. Running env will output a list like HOME=/home/ubuntu , USER=ubuntu , PATH=/usr/
local/sbin:... , etc. This shows key settings that programs inherit (like your home directory,
username, and search PATH).
- echo $<VAR> – Prints the value of a specific environment variable. For example, echo $HOME will
output something like /home/ubuntu , and echo $PATH prints the current PATH string. In the
course they likely used this to demonstrate checking or using variables.
- export <VAR>=<value> – Sets an environment variable for the current shell (and exports it to
subprocesses). For instance, export EDITOR=nano sets the EDITOR variable to “nano”. After this,
any program that looks at $EDITOR will see “nano”.
- Using ~/.bashrc or ~/.profile : The lecture might mention that you can persist environment
variables or aliases by adding export lines to your shell startup files like ~/.bashrc . E.g., adding
export EDITOR=nano in ~/.bashrc ensures it’s set every time you log in.
- printenv <VAR> – Another way to print a specific variable’s value (similar to echo $VAR ). E.g.,
printenv PATH outputs the PATH.
(In practice, environment variables configure the shell and programs. The course likely pointed out PATH
especially, since it determines where the shell looks for commands. They might have illustrated adding a
custom directory to PATH or creating a simple variable.)
8
Lecture 24: Command History and Aliases ( history , alias )
Shows how to use your shell’s history and define shortcuts: - history – Lists the command history
(commands you’ve entered). Each line is numbered. For example, you might see:
1 ls -l
2 cd /etc
3 history
This indicates ls -l was command #1, cd /etc was #2, etc. Knowing the numbers allows quick
reuse (with ! as shown next).
- !<number> – Re-runs a command from history by its number. If history shows that command 5
was sudo apt update , typing !5 will immediately execute sudo apt update again.
- !! – Shortcut for the last command. Useful for things like if you forget sudo , e.g. you run apt
install <pkg> and get a permission error, you can type sudo !! to rerun the last command with
sudo.
- alias – Creates an alias (shortcut) for a command. E.g., alias ll='ls -l' makes it so typing
ll will actually run ls -l . After defining this, ll /home would list the /home directory in long
format. Aliases often go in ~/.bashrc for persistence.
- Another example: alias gs='git status' (commonly used by developers to shorten a frequent
git command).
- unalias <name> – Removes an alias. If you set alias ll='ls -l' and want to remove it, use
unalias ll .
(The course likely encouraged customizing your shell to boost productivity and demonstrated recalling
commands from history to save time.)
Introduces processes and how to list them: - ps aux – Lists all running processes with detailed
information. In the output, each line corresponds to a process and includes columns like USER (owner),
PID (process ID), %CPU, %MEM, command name, etc. For example, the top of ps aux might look like:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 163248 8484 ? Ss May18 0:05 /sbin/init
syslog 1010 0.1 0.3 256000 12300 ? Ssl May18 1:20 /usr/sbin/
rsyslogd
ubuntu 20345 0.2 1.0 112648 42000 pts/0 S 13:00 0:00 nano
script.sh
This shows the system’s init process (PID 1), the syslog daemon, and an example of a user editing a file
with nano. The STAT column shows process state (S=sleeping, R=running, etc.).
- ps -ef – Another common syntax (System V style) to list processes with slightly different columns
(UID, PID, PPID, etc.). This may have been mentioned but ps aux is often sufficient.
- Filtering ps : The lecture might have re-emphasized combining with grep . For instance,
ps aux | grep apache to check if Apache web server processes are running (similar to the earlier
pipe example).
- Understanding PIDs: They likely pointed out the PID number and how each process has a unique ID.
This sets the stage for using kill by PID in the next lecture.
9
(In practice, ps is your go-to for snapshot of processes. The course snippet (Medium article) even specifically
cited ps aux as a must-know command for checking running processes.)
Introduces the interactive process viewer top : - top – Displays live system process information,
updated continuously. When you run top , you see a full-screen table of processes, along with CPU
and memory usage summaries at the top. Typically, top will show something like:
This shows two tasks: a bash shell and the top program itself. %CPU and %MEM show resource usage.
- Within top , you can press keys to sort or filter: e.g., press P to sort by CPU, M to sort by memory,
and q to quit. The course likely had you observe which processes are consuming the most resources
in real time.
- htop – They might mention htop as a more user-friendly alternative (with color and scroll
capability). If installed ( sudo apt install htop ), running htop provides similar info with a nicer
interface.
(System monitors like top are crucial for SREs to see live performance data. The lecture probably walked
through identifying processes and system load with top.)
Shows how to stop runaway or unneeded processes: - kill <PID> – Sends a termination signal
(SIGTERM by default) to the process with the given PID. For example, if ps shows a process with PID
1234 that’s hung, kill 1234 requests that it cleanly shuts down. Many programs will catch SIGTERM
and exit gracefully. There is typically no output from the kill command; you’d run ps again to see if
the process is gone.
- kill -9 <PID> – Sends SIGKILL (signal 9), which forces a process to stop immediately. For example,
kill -9 1234 will forcibly terminate PID 1234. This is used if a process doesn’t respond to a gentle
kill. (In practice, use this as a last resort because the process cannot clean up or save state on SIGKILL.)
- pkill <name> – Kills processes by name (pattern match). E.g., pkill python will send SIGTERM
to all processes with “python” in their name owned by you. This is convenient to kill multiple similar
processes without looking up each PID.
- killall <name> – Similar to pkill, it terminates all processes with the given name. For example,
sudo killall apache2 would attempt to kill all processes named “apache2” (useful to stop a web
server and its worker processes).
- Signals recap: They likely explained common signals: 15 (the default TERM) and 9 (KILL). Also
possibly -SIGINT (like Ctrl+C) and -HUP (hang-up, often used to reload configs). For instance,
kill -HUP <pid> tells some daemons to reload.
(The course almost certainly emphasized trying a normal kill first, then kill -9 if needed. In real SRE
tasks, you might kill a stuck process and then check with ps or top to ensure it’s gone.)
10
Lecture 28: Process Priorities ( nice and renice )
Explains how to adjust process scheduling priority: - nice -n <priority> <command> – Launches a
program with a given priority (niceness). Niceness values range from -20 (highest priority) to +19 (lowest
priority). By default, processes start at niceness 0. For example, nice -n 10 bigtask.sh will run
bigtask.sh at a lower priority, meaning it yields more CPU to other tasks. There may not be visible
output, but you could run top and see the NI (niceness) column for the process set to 10.
- renice <priority> -p <PID> – Changes the niceness of an already-running process. For
instance, sudo renice -5 -p 1234 would make PID 1234 higher priority (since -5 is above default).
Only root can increase priority (give more CPU) by setting a negative nice value. If you run renice
without sudo to a negative value, it will be denied.
- Use cases: They likely gave an example such as running a CPU-intensive script with low priority so it
doesn’t bog down the system ( nice for launching), or if a background process is too slow, you could
renice it to give it more CPU share.
(In practice, adjusting niceness is about being a “good citizen” on multi-user systems or balancing workloads.
DevOps folks use it when scheduling batch jobs or troubleshooting load issues.)
Covers managing processes in the shell without tying up your terminal: - <command> & – Adding an
ampersand at the end of a command runs it in the background. For example, python
long_script.py & will start the Python script, then immediately return you to the shell prompt so
you can continue working. You’ll see a line like [1] 2345 indicating job number [1] and PID 2345 for
the background job.
- jobs – Lists current background jobs in your shell with their job numbers and status. It might
output:
This shows job 1 is running, and job 2 is stopped (perhaps you suspended nano with Ctrl+Z). A +
denotes the default job for fg / bg if not specified.
- fg %<jobnumber> – Brings a background job to the foreground (resuming control of it in the
terminal). For example, fg %1 would take job 1 (from the above list) and bring python
long_script.py back to the foreground. If you omit the job number ( fg alone), it brings the most
recent job (marked with + ).
- bg %<jobnumber> – Resumes a stopped job in the background. For instance, if job 2 is nano
notes.txt and it’s stopped, bg %2 will resume nano but keep it running in the background (not
usually useful for editors, but good for processes that can run without interaction). Usually, you stop a
job with Ctrl+Z (which suspends it) and then can use bg to continue it in background.
- nohup <command> & – (No hang-up) Possibly mentioned: allows a command to keep running after
you log out. E.g., nohup backup.sh & runs the script immune to hangup signals, and output is
redirected to nohup.out . This is useful if you start a long job over SSH and want it to persist even if
your session closes.
(These shell job controls are handy for multitasking. In a DevOps scenario, you might start a server process in
background or suspend a foreground task if you need the shell for something urgent.)
11
Lecture 30: Scheduling Recurring Tasks with Cron ( crontab )
Introduces automated task scheduling using cron: - crontab -e – Edits the crontab (cron table) for
the current user in a text editor. Cron jobs are defined in the format minute hour day_of_month
month day_of_week command . For example, adding a line:
0 2 * * * /home/ubuntu/backup.sh
in the crontab will schedule /home/ubuntu/backup.sh to run at 02:00 (2 AM) every day. After saving
and exiting, the cron daemon will pick up the new job.
- crontab -l – Lists the current user’s cron jobs. If you’ve set the above job, crontab -l will
display it. If no cron jobs are set, this might output nothing or a message like “no crontab for user”.
- Cron service: The lecture likely explained that cron runs in the background and will execute tasks at
scheduled times. They might have given examples like scheduling maintenance scripts or periodic
checks (like a script to ping a server every 10 minutes, etc., by using an appropriate crontab entry).
- Cron special strings: Possibly mentioned that instead of numbers you can use nicknames like
@daily , @reboot etc. E.g., @daily /usr/bin/apt update -y would run daily.
(Automation of repetitive tasks is key for SRE. Cron is fundamental – e.g., schedule backups, clean temp files
weekly, etc. The course likely had you practice writing a simple cron job, then waiting or manually forcing it to
see it run.)
(If included; some courses include the at command for single-run jobs.)
- at <time> – Schedules a one-time task at a specific time. For example, typing at 3:00 PM then
pressing Enter, you enter an at prompt where you can type a command (say reboot ) and then
Ctrl+D . This would schedule a one-time system reboot at 3:00 PM today.
- atq – Lists pending at jobs (the queue). If you scheduled jobs, atq will show their job number
and scheduled time.
- atrm <jobnumber> – Removes a scheduled at job. E.g., if atq shows job 5 is your scheduled task
and you want to cancel it, atrm 5 will delete it.
(The at utility is less used than cron, but it’s handy for jobs you want to run only once at a later time. If the
course included it, they likely demonstrated scheduling a simple echo or shutdown using at .)
Explains how to check disk space usage: - df -h – Displays disk free space on all mounted filesystems
in human-readable format. The output has columns for filesystem, size, used, available, and use%. For
example:
This tells you how full each disk/partition is. -h makes it show GB/MB instead of raw bytes. This is the
go-to command when you suspect a disk is filling up.
- du -h <path> – Summarizes disk usage of the specified path. For example, du -h /var/log will
list the sizes of directories and files under /var/log . Typically, you’d use du -sh <path> to get a
summary (-s) total size of a folder. E.g., du -sh /var/log might output 200M /var/log , meaning
the logs directory uses 200 MB.
- du -h <path> --max-depth=1 – Shows the size of each immediate subdirectory in a given
12
directory (depth 1). For instance, du -h /home --max-depth=1 could output something like:
5.3G /home/alice
7.8G /home/bob
13.1G /home
indicating each user’s home directory size and the total for /home. This is useful to identify which
subdirectories are using the most space.
(The course likely had you practice checking disk usage, especially because running out of space is a common
issue. Knowing df helps you see if a filesystem is full, and du helps pinpoint large files or folders.)
Covers how to view disks and their partition layout: - lsblk – Lists block devices (disks and partitions)
in a tree form. Running lsblk might output:
This shows a 100GB disk sda split into two partitions (sda1 mounted at /, and sda2 at /home). sr0 is
a CD-ROM in this example. It’s a convenient overview of storage devices, their sizes, and mount points.
- sudo fdisk -l – Lists partition tables of all disks (requires sudo to read device info). This gives a
more detailed, text description of each disk’s partitions and their start/end sectors. For example, it will
show something like:
This confirms partition sizes and types. The * under Boot means /dev/sda1 is bootable.
- lsblk -f – (Possible mention) shows filesystems and their labels/UUIDs. For example, lsblk -f
would list each partition along with the filesystem type (ext4, swap, etc.) and identifier. This can be
helpful to identify which filesystem is on which partition.
(While DevOps engineers might not partition disks daily, understanding disk layout is important, especially
when adding storage or troubleshooting. The lecture likely showed how to identify all storage devices and
maybe distinguish a mounted drive vs an unmounted one.)
Explains how to mount storage devices (like USB drives or additional disks) and unmount them: -
mount – With no arguments, mount displays all currently mounted filesystems and their mount
points. This list includes devices and possibly special filesystems. For example, it might show a line:
13
/dev/sda1 on / type ext4 (rw,relatime)
Shows how to compress and decompress files for backup or transfer: - tar -cvf <archive.tar>
<files...> – Creates an archive (tarball) of specified files or directories. For example, tar -cvf
project.tar project/ will bundle the project/ directory into a single file project.tar . Flags:
c = create, v = verbose (list files as they’re added), f = filename of archive. As it runs, you’ll see a list
of files being added (because of v ).
- tar -xvf <archive.tar> – Extracts a tar archive. Using the above example, tar -xvf
project.tar will unpack the contents of project.tar into the current directory (recreating the
project/ folder and files). x = extract. You’ll see each file listed as it’s extracted (thanks to v ).
- tar -czvf <archive.tar.gz> <files...> – Creates a compressed tarball using gzip ( z flag).
For instance, tar -czvf logs.tar.gz /var/log/* will archive all files in /var/log and compress
them with gzip, resulting in a smaller logs.tar.gz . This one command replaces having to run gzip
separately.
- tar -tzf <archive.tar.gz> – Lists contents of a compressed tar archive without extracting.
Good for peek-checking what’s inside logs.tar.gz .
- gzip <file> – Compresses a single file using the gzip algorithm, adding a .gz extension. E.g.,
gzip large.log will create large.log.gz and remove the original large.log by default.
- gunzip <file.gz> – Decompresses a .gz file back to original form. E.g., gunzip
large.log.gz restores large.log .
- zip <archive.zip> <files...> – Creates a ZIP archive. For example, zip configs.zip
*.conf compresses all .conf files in the directory into configs.zip . Unlike tar, zip compresses
file by file and stores them in an archive.
- unzip <archive.zip> – Extracts a ZIP archive. unzip configs.zip will unpack the files (by
default into the current directory or specified path).
(The course likely used tar for backups – e.g., making a tar.gz of a project folder – and showed how to extract
it. They may have noted that .tar.gz (or .tgz ) is common on Linux, while .zip is common for cross-
platform sharing. Knowing both is useful.)
14
Lecture 36: Package Management Basics ( apt update , apt install )
Introduces using APT (Advanced Package Tool) on Ubuntu to manage software: - sudo apt update –
Fetches the latest package lists from repositories. It updates information about what packages (and
versions) are available. After running this, you’ll see a series of lines like Hit:1 http://
archive.ubuntu.com/... focal InRelease and so on, finishing with something like Reading
package lists... Done . This does not upgrade any software, it just refreshes metadata. (It’s
recommended to run this before installing new packages or upgrading.)
- sudo apt upgrade – Upgrades all installed packages to their newest available versions (after apt
update ). It will show a summary like XX packages can be upgraded. Y to upgrade, N to
cancel . If you proceed ( Y ), apt will download and install updates for your system. This is how you
apply routine updates (security patches, etc.).
- sudo apt install <package> – Installs a new package and any dependencies it requires. For
example, sudo apt install nginx will download and install the Nginx web server. Apt will show
the packages to be installed and how much data will be downloaded, asking for confirmation. After
installation, you can typically start using the package (e.g., Nginx’s service will be installed and possibly
started).
- sudo apt install <pkg1> <pkg2> ... – You can install multiple packages in one command.
e.g., sudo apt install git curl vim would install Git, cURL, and Vim in one go.
- Selecting “yes” automatically: The course might mention that adding -y (e.g.,
sudo apt install -y nginx ) auto-confirms prompts – handy for scripting but use carefully.
- apt show <package> – Shows details about a package, like its description, version, and
dependencies. For example, apt show bash would describe the Bash shell package. (Similar to apt-
cache show from older apt-get commands.)
(APT is central to managing software on Ubuntu. The lecture likely had you practice installing something
simple like the tree utility or htop for demonstration. They also probably explained the difference between
updating the package index vs upgrading installed packages.)
Lecture 37: Removing and Searching Software ( apt remove , apt search )
Covers how to uninstall packages and find available software: - sudo apt remove <package> –
Uninstalls a package but typically leaves its configuration files. E.g., sudo apt remove nginx would
remove the Nginx program files. If you planned to reinstall later, configs in /etc/nginx might remain. Apt
will list what it’s removing and prompt.
- sudo apt purge <package> – Removes a package and its configuration files. Using the same
example, sudo apt purge nginx would remove Nginx and delete its config files in /etc. This is
useful if you want a completely clean removal as if the package was never installed.
- sudo apt autoremove – Cleans up packages that were installed as dependencies but are no longer
needed. After removing some packages, you may see apt suggest running autoremove. Executing
sudo apt autoremove will uninstall those orphaned dependencies. This frees up disk space and
tidies the system. The output will list packages it’s going to remove (e.g., old libraries).
- apt search <keyword> – Searches the package repository for a given keyword. For example,
apt search editor will list packages with “editor” in their name or description (like gedit ,
nano , vim , etc.). This is useful to discover package names if you know the function but not the exact
name.
- apt list --installed – Lists all packages currently installed on the system. (This can be long.)
You might pair it with grep to find something, e.g., apt list --installed | grep nginx to
check if nginx is installed.
(The course likely walked through removing a test package installed earlier and using search to find new tools.
15
Understanding how to safely remove and clean up packages is important so that old dependencies don’t
accumulate clutter or security issues.)
Discusses controlling system services (daemons) using systemd’s systemctl : - sudo systemctl
status <service> – Shows the running status and recent log output of a service. For example,
sudo systemctl status ssh might output:
This indicates that the SSH server ( sshd ) is loaded, enabled to start on boot, and currently active
(running) with process ID 1234. You’d also see the last few log messages for the service (e.g., “Server
listening on port 22”).
- sudo systemctl start <service> – Starts a service immediately. E.g.,
sudo systemctl start nginx will launch the Nginx service right now. If it succeeds, running
systemctl status nginx will show it as active. (This does not enable it at boot unless you also do
enable.)
- sudo systemctl stop <service> – Stops a running service. For instance, sudo systemctl
stop nginx will gracefully shut down the Nginx service. After this, status nginx would show it as
inactive (dead).
- sudo systemctl restart <service> – Stops and then starts the service again. Useful after
changing configuration. E.g., sudo systemctl restart apache2 will reload Apache. If the service
was not running, restart will try to start it.
- sudo systemctl reload <service> – Reloads the service configuration without a full restart (if
supported by the service). For example, sudo systemctl reload ssh tells the SSH daemon to re-
read its config file without dropping existing connections. Some services differentiate between reload
and restart; others treat them similarly or don’t support reload.
(Controlling services is a daily task for Linux admins – the lecture likely had you practice starting/stopping
something like cron or an installed service like ssh or apache2 , and checking its status output.)
Explains how to configure whether a service runs at startup: - sudo systemctl enable <service>
– Configures the service to start automatically at boot. For example, after installing a new service like
mysql , you might run sudo systemctl enable mysql so that MySQL database starts whenever
the server reboots. This command creates the appropriate symlinks in systemd configuration to mark
the service for auto-start.
- sudo systemctl disable <service> – Prevents a service from starting at boot. For instance,
sudo systemctl disable apache2 ensures that Apache won’t auto-start on system boot (you’d
16
have to start it manually if needed). Disabling doesn’t stop a currently running service; it just affects
future boots.
- sudo systemctl is-enabled <service> – Checks whether a service is enabled to start at boot.
It will output “enabled” or “disabled”. E.g., systemctl is-enabled ssh might show “enabled” (since
SSH is usually enabled by default on servers so you can log in).
- Runlevels/Targets: The course might mention the concept of runlevels (SysVinit) vs systemd targets.
For example, enabling/disabling services replaces older update-rc.d commands. They might have
also noted systemctl set-default multi-user.target or graphical.target to switch
between console-only and GUI boot, though on a server course this may not be needed.
(Enabling critical services (like a database or web server) is something you’d ensure in production so it
recovers after reboots. The lecture likely gave a scenario: “we installed XYZ service, now enable it so it persists
across reboots.”)
Introduces how to read system logs for troubleshooting: - journalctl -xe – Shows the systemd
journal log with extra detail and continuously scrolls (like tail -f for logs, but with context of recent
errors). The -x flag provides explanations for log messages when available, and -e jumps to the end
of the log (most recent entries). This command is often suggested in error messages (for example, if a
service fails to start, the output might say “See 'journalctl -xe' for details”). Running it will display recent
log lines in a pager (use q to quit). It’s useful for seeing why a service failed.
- journalctl -u <service> – Filters the journal to messages from a specific service unit. For
example, journalctl -u nginx will show log entries for the Nginx service (both stdout/stderr from
the process and any service-related messages) in chronological order. You can add -b to filter since
the last boot or -f to follow. E.g., journalctl -u nginx -f to watch Nginx logs live.
- Traditional logs: The instructor may also have shown that many services still log to files in /var/
log/ . For example, tail -f /var/log/syslog or service-specific logs like /var/log/auth.log
for SSH, or /var/log/apache2/error.log for Apache. They might emphasize that on Ubuntu with
systemd, journalctl captures all these, but knowing where important log files live is still useful.
- Searching logs: You can search within journalctl output by piping to grep or using journalctl
| grep keyword . Alternatively, use journalctl -u service --since "2025-05-19 12:00" to
see logs since a certain time. They might have shown a basic filter by time or boot ( journalctl -b
for logs from current boot only).
(Log analysis is key for SRE troubleshooting. The lecture probably included an example of a service failing to
start, then using journalctl -u servicename to get the error (e.g., a missing config or port conflict)
and demonstrating how to fix it.)
Shows the proper commands to safely reboot or shut down the system: - sudo shutdown -h now –
Initiates an immediate shutdown (“halt”) of the system. The -h flag means halt/power-off, and now
means execute it immediately. After running this, users are notified and the system will go through the
shutdown process, terminating all processes, syncing disks, and powering off. (On some systems, you
might see a warning broadcast like “System is going down for halt NOW!”)
- sudo shutdown -r now – Reboots the system immediately ( -r for reboot). This is essentially
telling the OS to shut down and then restart. After issuing this command, your session will end as the
machine goes down and then comes back up.
- Scheduled shutdown: sudo shutdown -h +10 "System updating, please save work" –
This would schedule a shutdown in 10 minutes and broadcast a message to all logged-in users. The
users would see “System updating, please save work” along with a countdown. This can be canceled
17
with sudo shutdown -c if needed.
- reboot – A shortcut command (requires sudo or root) that is equivalent to shutdown -r now on
most Linux distributions. So sudo reboot will immediately reboot.
- halt or poweroff – Similar shortcuts for shutting down. sudo poweroff is like shutdown -h
now .
(The course likely reminded that you should use these commands rather than just hitting a power switch – to
ensure services stop gracefully and filesystems don’t get corrupted. It might also note that on a remote server,
running these will disconnect your session as the machine goes down.)
Sets the stage for writing shell scripts: - Shebang ( #! ) – Not a command, but the first line in a script
file like #!/bin/bash . This tells the system that this file should be run with the Bash interpreter. The
lecture likely had you create a file, e.g. script.sh , with a first line #!/bin/bash followed by some
commands.
- Writing a simple script: Using an editor ( nano script.sh ), they might include lines like:
#!/bin/bash
echo "This is my first script"
whoami
The echo and whoami here are commands that will run when the script is executed.
- chmod +x script.sh – Makes the script executable. After saving the script, you run chmod +x
script.sh to give it execute permission. Without this, you’d have to run it with bash script.sh
explicitly. With the permission set, you can do the next step.
- ./script.sh – Executes the script from the current directory. The output would be:
(assuming the current user is ubuntu, the script prints the message and then the username via
whoami ). The lecture’s goal here was to show how to create a basic script and run it.
- Script execution paths: They probably mentioned that ./script.sh runs a script in the current
directory (which must be in your PATH or you prefix with ./ ). If you move the script to a directory in
your PATH (like /usr/local/bin ), you could run it by name from anywhere.
(By automating commands in scripts, DevOps engineers can repeat tasks easily. This intro shows the
mechanics of script files, which the following lectures build on.)
Covers using variables and reading input: - Defining variables: In Bash, you assign without spaces. E.g.,
NAME="Alice" . The script can then use $NAME to get the value. For example:
18
#!/bin/bash
NAME="Alice"
echo "Hello, $NAME"
Running this would output: Hello, Alice . They likely emphasized not to put spaces around the =
and that variable names are case-sensitive by convention.
- Using variables from environment: If you run a script and the variable is already defined in the
environment, you can access it. For example, $HOME or $USER can be used directly. In a script,
echo "Home directory: $HOME" would print the home directory path of the user running the
script.
- read <variable> – Pauses the script and waits for user input, then stores it in the given variable.
For instance:
If the user types “Bob” and presses enter, the script will output “Nice to meet you, Bob!”. The -n flag
with echo ensures the prompt stays on the same line as user input.
- Positional parameters: Not explicitly mentioned above, but often taught: $0 is the script name,
$1 , $2 , ... are arguments passed to the script. For example, if you run ./greet.sh Alice , inside
greet.sh you can use $1 to get “Alice”. They might have shown a simple example:
#!/bin/bash
echo "Hello, $1"
Shows how to make decisions in scripts using if : - if ... then ... fi – Basic if structure. For
example:
Here [ "$USER" = "root" ] is a test expression (using the test command shorthand with
brackets). If the condition is true, the then block executes; otherwise the else block executes. In a
script, if you run this as root it would print “You are root”, otherwise “You are not root”.
19
- [ ] (test) – The [ is actually a command (alias for test ). Common test expressions:
- String comparison: = (equal), != (not equal).
- Numeric comparison: -eq , -ne , -lt , -gt , etc. e.g., [ "$COUNT" -gt 5 ] checks if $COUNT >
5.
- File checks: -f file (file exists and is a regular file), -d dir (directory exists), -e path (exists),
-s file (file is not empty), -x file (executable), etc. For example:
if [ -d "/backup" ]; then
echo "/backup directory exists"
fi
This will print the message only if the /backup directory is present.
- elif – Else-if ladder for multiple conditions. For example:
case $ANSWER in
[Yy]|[Yy][Ee][Ss]) echo "You answered yes";;
[Nn]|[Nn][Oo]) echo "You answered no";;
*) echo "Invalid answer";;
esac
This matches $ANSWER against patterns. Useful for menu selection scripts.
(With conditionals, scripts can react to different inputs or system states. The course likely had you write a
simple script that checks something (like number of arguments, or existence of a file) and prints different
outcomes.)
Demonstrates automation by repeating actions in scripts: - for loops (list iteration): Example:
20
mkdir /home/$USER
done
This loop iterates over a list of names and executes the do block for each, here printing a message
and making a directory. If run, it would output “Creating home directory for alice” etc., and create those
directories (assuming appropriate permissions).
Another common pattern is looping over files:
This would iterate over all .log files in a directory and add them to an archive logs.tar (using -r
to append to tar).
- C-style for loops: Bash also supports a C-like syntax:
This will print Count 1 through Count 5. They might have shown this to demonstrate arithmetic loops.
- while loops: Example:
COUNT=1
while [ $COUNT -le 5 ]; do
echo "Number $COUNT"
COUNT=$((COUNT + 1))
done
This will loop while COUNT is <= 5, printing “Number 1”, “Number 2”, etc., then stop. The COUNT=$
((COUNT + 1)) is arithmetic expansion to increment the counter.
- until loops: Possibly mentioned. Similar to while but runs until the condition becomes true. E.g.,
This would keep pinging a host every 5 seconds until it responds, then exit the loop. This demonstrates
a practical use: waiting for a service to become available.
- break and continue : They might illustrate breaking out of a loop or skipping to next iteration. For
example, inside a for loop, if [ "$x" = "stop" ]; then break; fi to exit early if a condition
is met. Or continue to skip rest of loop body for the current item.
(Loops are crucial for tasks like batch processing files or repetitive tasks. The course likely had an exercise to
loop through users or iterate through lines in a file using for , or a simple while loop to retry an action until
success.)
21
Lecture 46: Creating Functions in Bash Scripts (Reusable Code Blocks)
(If covered, many admin courses do include Bash functions for completeness.)
- Defining a function:
myfunction() {
echo "Hello from inside a function"
}
This creates a function named myfunction . It can be called later in the script by simply writing
myfunction on a line. When called, it will execute the commands inside.
- Function with parameters: Inside a function, $1 , $2 , etc. refer to the function’s arguments
(separate from script’s arguments). E.g.,
greet() {
echo "Hello, $1!"
}
greet "Alice"
When greet "Alice" runs, inside the function $1 is “Alice”, so it prints “Hello, Alice!”. This way you
can reuse logic with different inputs.
- Returning values: Bash functions don’t return values like traditional programming (they return an exit
status 0-255). Instead, you typically output the result and capture it or use global variables. They might
not dive too deep here, mostly focusing on basic usage.
- Use case: The course may show a function for repetitive tasks, like a function to log messages with
timestamps or a function to check if a service is running (using systemctl) that you can call multiple
times with different service names.
(Functions help organize larger scripts. If included, it reinforces DRY principles. The lecture might have been
brief on this, showing how to declare and call a function within a script to modularize the code.)
This lecture likely walks through a real-world script that uses the concepts learned (variables, if, loops)
to perform a task, such as backing up a directory: - Scenario: Backup a given folder (e.g., /var/www )
to an archive with date in filename, and maybe automate deletion of old backups.
- Commands in the script:
- Use of date: $(date +%F) – This captures the current date in YYYY-MM-DD format (e.g., 2025-05-19).
If used in a script, e.g., BACKUP_FILE="webBackup-$(date +%F).tar.gz" , you get a filename like
webBackup-2025-05-19.tar.gz . This was likely shown to illustrate dynamic names.
- Using tar to create the backup: e.g.,
22
if [ $? -eq 0 ]; then echo "Backup successful"; else echo "Backup failed";
fi
$? holds the exit code of the last command (0 means success). This pattern is common to verify if a
command executed properly.
- Possibly removing old backups: using find in a script to delete archives older than X days. e.g.,
This would remove backup files older than 7 days (housekeeping). They might mention this but even if
not fully implemented, it’s a typical addition.
- Cron automation: They likely tie this with cron: once the script works, schedule it via cron to run daily
at 2am, for instance (which was already taught). So you have a fully automated backup system.
(This practical example wraps up the scripting section by showing how all the pieces come together to solve a
real task. It also reinforces the use of previously learned commands in a script context.)
Covers techniques to debug scripts or avoid common errors: - set -x (execution tracing) – When
added in a script (or run via bash -x script.sh ), it prints each command and its arguments to the
terminal as they execute. This is useful to trace what the script is doing, especially to pinpoint where it
might be going wrong. Typically you’ll see lines prefixed with + showing expanded variables. For
example, if your script has NAME="Bob" and echo "Hello $NAME" , with set -x you’d see:
+ NAME=Bob
+ echo 'Hello Bob'
Hello Bob
This helps in debugging logic errors or verifying that variables hold expected values at runtime.
- set -e – Another shell option: exit immediately if any command returns a non-zero status (error).
This can make scripts safer by not blindly continuing after a failed command. Many scripts start with
set -e so that if, say, tar fails (maybe the source dir is missing), the script will stop rather than
proceeding on and possibly doing something unintended.
- shellcheck – A static analysis tool that points out common mistakes in shell scripts. If you run
shellcheck script.sh , it will output warnings/errors for things like unused variables, quoting
issues, deprecated syntax, etc. It’s not a built-in command by default, but is available via package
( sudo apt install shellcheck ). The course may have shown using an online shellcheck or
installing it to demonstrate catching an error (like forgetting to quote a variable with spaces).
- Using echo for debugging: In lieu of or in addition to set -x , simply printing out variable values
at certain points can help. E.g., echo "DEBUG: X is $X" in a script to see what X is at that time. This
informal method might have been recommended for simpler troubleshooting.
- Common pitfalls: They might mention pitfalls such as forgetting to make a script executable, or the
difference between running a script with bash script.sh (which runs in a subshell) vs sourcing it
with . script.sh (which runs in the current shell – not usually what you want unless specifically
updating the current shell’s environment). Possibly an example: running a script that sets an
environment variable and expecting it to persist – it won’t unless you source it.
(This lecture ensures students know how to diagnose script issues, which is crucial as scripts grow. set -x
23
in particular is a quick way to see the script flow, so likely they demonstrated turning it on to find a bug in a
sample script.)
Introduces how to view and understand network configuration on Linux: - ip addr show – Displays
all network interfaces and their IP addresses (using the modern ip command suite). The output will
list interfaces like lo (loopback), eth0 or ens33 (Ethernet), etc., with their IPv4 and IPv6 addresses,
for example:
This indicates interface ens33 has IP 192.168.1.10 with a /24 netmask. The lecture would explain
components like netmask (/24 means 255.255.255.0), broadcast address, etc., and that state UP
means the interface is enabled.
- ifconfig – An older command (from net-tools) that many use similarly to check IPs. On modern
Ubuntu, ifconfig might not be installed by default, but if it is, ifconfig shows interfaces and
their IPs. For example:
They likely noted that ip addr is the preferred new tool, but ifconfig is common and may need
installation ( sudo apt install net-tools ) if one tries to use it.
- ip route show – Displays the routing table. The output might look like:
This tells us the default gateway is 192.168.1.1 (the router), and any traffic for 192.168.1.0/24 (local LAN)
is directly reachable on ens33. The course likely explained what a default route is and how traffic flows
to the internet via the gateway.
- Bringing interfaces up/down: Possibly shown: sudo ip link set ens33 down to disable an
interface, and sudo ip link set ens33 up to bring it back up. (On a server you’d rarely do this
manually except for debugging, but it’s instructive.) If ifconfig was used, sudo ifconfig ens33
down does the same.
- Assigning IP (maybe): If they demonstrated static config temporarily: sudo ip addr add
10.0.0.5/24 dev ens33 would assign a new IP. And sudo ip addr del 10.0.0.5/24 dev
ens33 removes it. (However, permanent config should be done via netplan or /etc/network/
interfaces on older systems, which they might have touched on conceptually.)
(Understanding your IP and network is fundamental. The lecture likely emphasized interpreting ip addr
24
output and identifying the local IP, netmask, etc., and possibly how to change it, though cautioning that
manual changes are lost on reboot unless configured properly.)
Shows how to verify network connections and paths: - ping <host> – Sends ICMP echo requests to a
host to check reachability. For example, ping 8.8.8.8 will send repeated pings to Google’s DNS
server. A successful ping output looks like:
This indicates replies are being received (with times ~10ms). They likely demonstrated pinging a local
gateway or another server. On Ubuntu, ping continues until stopped; you press Ctrl+C to end it,
after which ping will show statistics (packet loss, average time).
- ping -c <count> <host> – Pings a specified number of times and then stops. E.g., ping -c 4
8.8.8.8 will send 4 pings and then summarize. This is useful for scripting or just quick checks without
infinite output.
- ping <hostname> – Also tests DNS if using a name. For example, ping www.google.com will first
resolve that hostname to an IP, then ping it. If name resolution fails, you know there might be a DNS
issue.
- traceroute <host> – Maps the route that packets take to reach a host, showing each hop (router)
along the way and the latency to each. For example, traceroute 8.8.8.8 might output:
This shows the path from your machine (hop 1 is your router) through ISP routers, etc., until Google’s
server. Times are given for each hop. If a traceroute hangs at some hop or shows * * * , that hop
might be filtering traceroute or there’s a break in the path.
- mtr <host> – They might mention mtr (My Traceroute, needs install) as a real-time traceroute/
ping combo tool. Not sure if covered, but if yes: mtr google.com continuously shows each hop and
packet loss, which is great for network diagnostics.
(SREs often use ping to see if a service is up or to measure latency, and traceroute to find where connectivity
issues arise. The lecture likely included a live demo of pinging an external site and interpreting TTL and time,
plus a traceroute to illustrate how traffic travels on the internet.)
Focuses on resolving hostnames to IP addresses and vice versa: - nslookup <hostname> – Queries
the DNS for the IP address of a given hostname. For example, nslookup www.example.com might
output:
25
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: www.example.com
Address: 93.184.216.34
This shows the DNS server used (in this case the router at 192.168.1.1) and the resolved IP. “Non-
authoritative” means the answer is from a cache or not directly from example.com’s own DNS servers. If
a domain has multiple IPs, nslookup will list them.
- nslookup <IP> – Doing a reverse lookup (IP to hostname). E.g., nslookup 8.8.8.8 might return
a name like dns.google . If no PTR record exists, it may show “NXDOMAIN” or just the ISP’s info.
- dig <name> – A more powerful DNS lookup tool (not always installed by default, part of dnsutils).
For example, dig example.com gives detailed output including DNS query time and authority. The
answer section will list A records for example.com. dig by default queries the A record (IPv4).
- dig <name> ANY can fetch all record types, dig <name> MX for mail servers, etc.
- dig +short <name> gives a concise output (just the IP addresses). E.g.,
dig +short google.com might list several IPs.
- /etc/hosts – A static file to map hostnames to IPs locally. They likely showed an example entry:
127.0.0.1 localhost
10.0.0.50 testserver
With that entry, you can ping testserver and it will resolve to 10.0.0.50 without querying DNS. The
hosts file is checked first by the resolver (unless changed). This is handy for test environments or
overriding DNS in a pinch. They probably cautioned to be careful with /etc/hosts (e.g., not to leave
bogus entries that override real DNS unintentionally).
- host <name> – Another simple DNS lookup utility, similar to nslookup but with concise output. E.g.,
host example.com returns example.com has address 93.184.216.34 . They may or may not
have shown this if nslookup and dig were covered.
(Understanding DNS is critical. The lecture likely had you use nslookup to find IPs of known sites, and
possibly edit /etc/hosts temporarily to demonstrate name resolution order. This helps in troubleshooting cases
where a server can’t resolve names or when you want to test using a different IP for a hostname.)
Shows how to check which ports are open/listening on your system and what processes are using them:
- sudo netstat -tuln – Lists tCP and uDP listening sockets with numeric addresses (so it doesn’t
try to resolve hostnames for speed). The output might include lines like:
This indicates an SSH server (tcp port 22) listening on all interfaces, a MySQL server (tcp port 3306)
listening on localhost only, and a UDP service on port 68 (DHCP client). The Foreign Address * means
“any”.
26
- ss -tuln – Does a similar job to netstat for sockets (ss is the modern replacement from iproute2).
ss -tuln output is formatted slightly differently but shows the same info: port numbers and
listening addresses. If netstat isn’t available, ss is the go-to.
- sudo netstat -plant – A variant adding p (show PID/program name for each socket) and a (all
sockets, including listening and established), and t (TCP) + n (numeric). This is very useful: it will
show which process (by PID/name) is listening on which port. For example, it might show:
That tells us Nginx (PID 1045) is listening on port 80, and sshd (PID 980) on port 22.
- sudo lsof -i:<port> – Lists the process using a specific port. For instance,
sudo lsof -i:3306 will show something like:
This confirms mysqld is listening on port 3306. lsof -i can also take @host or protocol
qualifiers, but for quick use specifying the port is common.
- lsof -i with no filter lists all network connections with the process info, similar to netstat -p . It
can be a lot of output, so typically you filter by port or service.
- Use cases: They likely showed how to determine what’s keeping a port busy. E.g., if Apache won’t start
because something is on port 80, you can sudo lsof -i:80 to see what process is occupying it. Or
using netstat/ss to list all listening ports so you know which services are active.
(Knowing how to find open ports and their owning processes is key for diagnosing network issues (e.g., “Is my
service running and listening on the expected port?” or “What is this port I see open?”). The lecture definitely
included examples of checking commonly used ports like 22, 80, 3306, etc.)
Teaches how to secure the system using Ubuntu’s UFW front-end for iptables: - sudo ufw status –
Shows the current firewall status and rules. Initially, it might say Status: inactive (if firewall is off).
If active, it will list rules like:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
This indicates SSH, HTTP(80), HTTPS(443) are allowed. The v6 lines are IPv6 equivalents.
- sudo ufw enable – Enables the firewall (starts blocking/allowing per rules). When you run this,
UFW will warn if you have no rules, possibly locking you out. On Ubuntu, enabling UFW with no rules by
27
default allows SSH if it’s running (to not cut off remote admin). The course likely emphasized enabling
after adding needed rules.
- sudo ufw disable – Turns off the firewall (all traffic allowed, essentially). Useful for temporarily
testing or if you mis-configured something and got locked out (if you have console access).
- sudo ufw allow <service/port> – Allows incoming traffic on a port or predefined service. E.g.,
sudo ufw allow 22 or sudo ufw allow OpenSSH opens port 22 (SSH). sudo ufw allow 80/
tcp opens TCP port 80 (HTTP). If you have an app listening on a custom port, you specify the number.
You can also restrict by source or subnet: e.g., sudo ufw allow from 192.168.0.0/24 to any
port 3306 to allow only the local network to access MySQL.
- sudo ufw deny <port> – Explicitly block port. Often not needed if default is to deny, but for
completeness: e.g., sudo ufw deny 23 could explicitly drop telnet port 23.
- sudo ufw delete allow <rule> – Removes a rule. For example, if ufw status numbered
shows rule 3 is “80 ALLOW”, you could do sudo ufw delete 3 or the full rule syntax to remove it.
- Default policy: sudo ufw default deny incoming & sudo ufw default allow outgoing –
This is usually the default: block unsolicited incoming, allow all outgoing. They might mention it so you
know that by enabling UFW without rules, it’s secure by default except needed services you open.
(The lecture likely walked through allowing SSH (so you don’t lock yourself out), enabling UFW, then adding
rules for a web server, etc. It’s a straightforward but important step in securing a server. They probably also
tested it: e.g., enabling UFW then trying to ping (which by default UFW allows) or trying to access a closed
port to show it’s blocked.)
Lecture 54: Security Best Practices – Users, File Permissions, and SSH Hardening
Focuses on various security practices (though not one specific command-heavy topic, likely a mix of tips
using known commands): - Least privilege principle: They might discuss ensuring only necessary
privileges are given. Commands relevant: using chmod to remove world-writable rights, using sudo
carefully, etc. For instance, demonstrating removing sudo rights from a user using gpasswd -d
username sudo if needed.
- File permission scenarios: e.g., setting important config files to 600 (owner only). They might show
chmod 600 /etc/ssh/ssh_host_rsa_key (which should be that by default) as an example of
proper perms on sensitive files. Or ensuring scripts that contain secrets are not world-readable.
- sudo visudo and sudoers security: Perhaps a mention that you should limit who is in the sudo
group. They might have shown how to give a specific command permission via sudoers, but that’s more
advanced. Possibly just advice: use groups and sudoers rather than giving out root password (which on
Ubuntu root account is typically locked anyway).
- Disabling root SSH login: They might instruct checking /etc/ssh/sshd_config for
PermitRootLogin no (which is default on Ubuntu). Possibly using sudo nano /etc/ssh/
sshd_config to show that setting, then sudo systemctl reload ssh to apply if changed.
- Changing SSH port or using key authentication: Possibly mentioned as hardening tips. Commands
might include:
- Generating SSH key: ssh-keygen -t ed25519 (or rsa) to create a key pair. Then copy pubkey with
ssh-copy-id user@server .
- After key setup, disabling password auth: editing /etc/ssh/sshd_config to set
PasswordAuthentication no , then reload ssh .
- If changed port: update Port 2222 in sshd_config and then use ufw allow 2222 accordingly.
- fail2ban : If included, they might have sudo apt install fail2ban and mention that it
monitors logs and bans IPs after failed logins. Checking its jail status: sudo fail2ban-client
status sshd . This may be beyond the basics, but some courses introduce it as an easy win for SSH
security.
(This lecture is less about new commands and more about using existing tools to lock down the system. It
28
likely highlighted using the commands already learned (chmod, usermod, ufw, editing config files with nano/
vim, etc.) in a security context. Since it said “security settings” in course description, these are probably what
was covered.)
Dives deeper into monitoring memory and system load: - free -h – Shows memory usage in human-
friendly units. Output looks like:
They would explain the fields: total memory, used (currently in use by processes), free (truly free), buff/
cache (memory used by buffers/cache which can be freed if needed), and available (an estimation of
how much could be used without swapping). The course likely stressed that “used” appears high
because Linux caches things (hence look at “available” for a better sense of free memory).
- uptime – Prints how long the system has been running, how many users, and the load averages.
Example:
This means the machine’s been up 5 days, 2 users logged in, and load averages over 1, 5, 15 minutes
are low (0.05 etc.). They’d explain load average (0.05 is practically idle, 1.00 ~ one core fully busy if single
CPU, etc.). If this was a multi-core system, a load of 2.0 might still be fine if 4 cores exist.
- w – (already covered in Lecture 22) also includes uptime and load at top, but they might reuse it here
to interpret load.
- vmstat – Reports various system statistics. vmstat 1 5 for example prints 5 samples at 1-second
intervals of CPU, memory, I/O stats. Output columns include r (runnable processes), free (free
memory), bi , bo (block in/out for disk), and CPU breakdown ( us user, sy system, id idle, etc.).
They might not dive deep, since vmstat is a bit more advanced, but possibly mention it’s an all-in-one
glimpse for performance tuning.
- top – Already covered in Lecture 26. Might be re-mentioned as a key tool for seeing CPU and
memory per process to identify hogs if system is slow. Perhaps highlighting things like press M in top
to sort by memory usage.
- dmesg – Shows kernel ring buffer messages (system messages, often hardware or driver related).
Running dmesg | tail might show recent messages, like plugging in a USB drive or an OOM (Out-
Of-Memory) killer event. If the system had an OOM, dmesg would log it. The course might have
mentioned using dmesg to troubleshoot hardware or to check for kernel errors.
(An SRE needs to know if a system is under memory pressure or CPU overload. These tools help identify that.
The lecture likely had you observe memory usage with free after opening some programs, or explained
load average meaning to interpret if the server is overburdened.)
Discusses system limits and observing open files (particularly for tuning): - ulimit -a – Shows all
current shell limits for the user. You’ll see output like:
29
core file size (blocks, -c) 0
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
They’d highlight the “open files (-n) 1024” which is the max number of files a process can open (soft
limit). Also, things like stack size, etc.
- ulimit -n <number> – Sets the maximum number of open files (soft limit) for the current shell/
process. For example, ulimit -n 2048 would allow processes launched from that shell to open up
to 2048 files. This is often needed for databases or web servers under high load. They might
demonstrate raising it temporarily and explain for permanent changes you’d edit /etc/security/
limits.conf or systemd service files.
- ulimit -u <number> – Sets max user processes limit. Probably not changed in course, but they
might mention it if discussing preventing fork bombs.
- cat /proc/sys/fs/file-max – Shows the system-wide limit on open files. For instance it might
print 100000 meaning the kernel can track up to 100k open file descriptors system-wide. This can be
increased via sysctl if needed.
- lsof – Already partly covered for networking, but lsof without options lists all open files by all
processes (very large output). They might show lsof | wc -l to count open files, or lsof -u
username to list open files by a specific user. Possibly lsof /path/to/file to see which process
has a particular file open (useful when you can’t unmount a disk because something’s in use, for
example).
- File descriptor leak scenario: They might describe a case where a program runs out of file
descriptors (e.g., too many logs open) – raising ulimit -n or closing files is the solution.
(This topic is somewhat advanced, but given “optimize for high performance” in the course aims, they likely
touched on it. It’s important when tuning servers like Nginx or databases where you raise ulimit -n to
allow more concurrent connections/files. The lecture might not have heavy hands-on besides showing the
current limits and perhaps bumping one in a practice scenario.)
Shows how to view and modify kernel parameters dynamically: - sysctl -a – Lists all kernel
parameters (sysctl settings) and their current values. This is a long list (covering networking, VM, etc.).
They likely did not scroll through everything but mentioned you can grep for what you need. For
example, sysctl -a | grep swappiness might show vm.swappiness = 60 (the default
swappiness value).
- sysctl <name> – Query a specific parameter. E.g., sysctl net.ipv4.ip_forward would output
net.ipv4.ip_forward = 0 (off by default). This setting controls whether the server acts as a router
by forwarding packets.
- sudo sysctl -w <name>=<value> – Change a kernel parameter at runtime. For example, sudo
sysctl -w net.ipv4.ip_forward=1 will enable IP forwarding immediately (common when setting
up the server as a router or for Docker’s needs). After running that, sysctl net.ipv4.ip_forward
would show it’s now 1.
- Another example: sudo sysctl -w vm.swappiness=10 would decrease swappiness (tendency to
use swap).
- Persisting changes: They probably explained that edits via sysctl -w are not permanent – after a
reboot, they revert. To make them permanent, you add them to /etc/sysctl.conf or a file under /
etc/sysctl.d/ . For instance, adding vm.swappiness=10 to /etc/sysctl.conf will apply on
30
each boot (or run sudo sysctl -p to load from that file immediately).
- Examples of useful tunings: Could mention
- fs.file-max (system max open files) if needing to handle more open files globally (ties to ulimit
discussion).
- net.core.somaxconn (max TCP connection backlog) which affects how many pending connections
a server can queue – sometimes raised for high traffic web servers.
- net.ipv4.tcp_syncookies (for mitigating SYN flood attacks) – often left default but maybe
touched in security context.
- vm.overcommit_memory (how kernel handles memory allocation vs physical) – perhaps too deep for
course context.
Possibly they kept to simpler ones like enabling IP forwarding or tweaking network buffers if at all.
(Tuning sysctls is a more advanced admin skill. The course likely gave one or two common examples to show
the mechanics, such as enabling forwarding or adjusting swappiness for performance. They would emphasize
caution – only change parameters when you know what they do.)
Lecture 58: Using Linux in Cloud Environments (Connecting to AWS EC2 via SSH)
Discusses peculiarities or steps for using Linux on cloud platforms: - Key-based authentication: For an
AWS EC2 instance, you typically connect with a private key (PEM file). They’d show using ssh :
This uses the key for authentication (must have chmod 400 MyKey.pem so that the key file is not
publicly readable – SSH demands that). They likely demonstrated connecting to a cloud VM if the course
had a cloud segment.
- Cloud-init: They might mention that cloud VMs often use cloud-init to set up things (like your default
ubuntu user authorized key). Not much command here, more conceptual.
- Hostname and metadata: Possibly showing curl http://169.254.169.254/latest/meta-
data/ on EC2 to retrieve instance metadata (like instance ID, etc.), as a curiosity.
- Scaling considerations: They may not have specific commands, but talk about treating servers like
cattle (spin up instances as needed). Possibly showing how one might script launching cloud instances
(though actual aws CLI usage would require installing AWS CLI and credentials – maybe out of scope).
Possibly just conceptual or pseudo-commands.
- Using scp for cloud: Example if transferring files to cloud server:
This would securely copy the backup file to the cloud instance.
(This lecture is likely conceptual, preparing learners to apply their Linux skills on cloud VMs. The main
command used is ssh with keys and maybe mention of scp and setting up keys through cloud console. If
it’s hands-on, they might have spun up an AWS free-tier instance and connected via SSH to show it’s the same
Linux inside.)
Shows containerization basics on a Linux system: - Installing Docker: They might have walked through
sudo apt install docker.io (or using the official script) to get Docker on Ubuntu. After install,
possibly add user to docker group: sudo usermod -aG docker $USER so you don’t need sudo for
docker (requires re-login).
31
- docker run hello-world – Tests the installation by running a test image. The output of this
command is significant: Docker will pull the hello-world image if not present, then run a container
which prints:
Likely a high-level overview of Kubernetes in context – perhaps not a live demo but could mention
interacting with K8s: - kubectl – The Kubernetes CLI. They might show a couple of example
commands, assuming a cluster is set or using minikube:
- kubectl get nodes – lists the nodes in the Kubernetes cluster (should show at least one with
status Ready if minikube or similar).
- kubectl get pods --all-namespaces – lists all pods in all namespaces, to show system and user
pods. Without a cluster, maybe just screenshot or explanation.
- Possibly demonstrate deploying a container: e.g., kubectl run nginx --image=nginx --
port=80 which creates a deployment running Nginx. Then kubectl expose deploy/nginx --
type=NodePort --port=80 to expose it. Finally kubectl get svc to show a service. But that
might be too deep for a quick intro.
- No heavy new commands beyond using kubectl which has many subcommands. They likely focus on
concept that kubectl is how you control K8s, and show a get pods or similar output:
32
configuring credentials, reinforcing that Linux commands (and YAML config) are used to manage apps
in K8s.
(This being a job-ready course, they probably briefly touched on K8s to ensure awareness, but details would be
minimal. The key takeaway: you’d use kubectl to interact with Kubernetes clusters, and as an SRE you
should be comfortable in a Linux CLI to manage such modern infrastructure.)
This lecture likely ties together how the Linux skills apply in DevOps automation: - Using shell scripts in
CI: They might give an example of a snippet from a Jenkins pipeline or GitHub Actions where you run
shell commands. E.g., a stage that does:
npm install
npm test
or uses bash deploy.sh – emphasizing that behind popular CI/CD tools, it’s often executing Linux
commands on an agent.
- Build automation: Possibly mention tools like make or bash scripts used to compile code or run
containers during CI. No new specific commands here, just contextual usage of existing ones.
- Environment variables in CI: e.g., $CI_COMMIT_SHA or so, showing that those become
environment variables in shell in a CI environment – tying back to the lecture on env vars.
- Example: They could have shown a very simple pipeline script or at least described it, such as:
build:
stage: build
script:
- echo "Building project on $(uname -n)"
- ./gradlew build
The idea being that knowledge of Linux CLI (like uname -n showing hostname or running build tools)
is used inside CI definitions.
- No actual tool usage likely, but maybe a mention of installing Jenkins (via apt), though that’s probably
beyond scope. More likely theoretical. If anything, maybe showing curl -s https://someci to
emphasize automation can be triggered with CLI tools as well.
(This was probably a concluding lecture bridging how what was learned is used in the broader DevOps
workflow. The commands mentioned would be ones already known – reaffirming that automation pipelines
are essentially executing these commands to build, test, deploy software.)
No commands here. Likely a summary of best practices, encouragement to keep practicing, possibly
references to further learning or certifications (like Linux Foundation, RHCSA, etc.), and closing remarks
by the instructor.
Note: Many later lectures (especially beyond 60) in the course were scenario-based (labs, Q&A, or
project walkthroughs) rather than introducing brand new commands. The commands listed above
encompass all standard commands and their primary usage as taught in the course. Subsequent
practice or interview question lectures reused these commands in troubleshooting contexts (for
33
example, using systemctl and journalctl to fix a failing service, or using grep / find to parse
logs for an error). Refer back to the relevant lecture cheat sheet entry when revisiting those scenarios
for a refresher on command usage. This concludes the comprehensive command reference for each
lecture of the course. Good luck with your DevOps and SRE journey!
34