OnCallReady

Lesson 1.11 · First Login · 14 min read

Packages and sudo

In plain words

Picture a school where only the head teacher can open the supply cupboard. Instead of giving you the head's keys, the school gives you a pass: show it once and the caretaker opens the cupboard for one request, writes your name in a book, and remembers your face for 15 minutes.

That pass is sudo. It runs one command as root, asks for your own password, and logs it. The trap: if you say "caretaker, put this note in the cupboard" but you are the one carrying the note in, the door is still locked for you. That is sudo echo x > /etc/f: the shell, as you, opens the file. apt update is checking the catalogue for what exists; apt upgrade is actually swapping the old supplies for new.

You need a tool that is not installed, or a setting changed in /etc. You type the command and get Permission denied. You add sudo and it still says Permission denied. This lesson is how you get admin rights for one command, why that second failure happens, and how software gets installed on Ubuntu.

What you need to know already: 1.5 Making things (> redirection is done by the shell), 1.7 Driving the shell (&&, pipes).

Root, and sudo

Every user has a number, the UID (user ID). You are learner, UID 1000. The root user is UID 0, and the kernel lets UID 0 do almost anything. Everything outside your home directory - system settings in /etc, installed programs - can only be changed by root.

sudo (superuser do) runs one command as root. It asks for your password (not root's - on Ubuntu the root account has no password at all, so you cannot log in as root directly), checks that you are allowed, and writes a log line saying who ran what.

$ sudo whoami
[sudo] password for learner:
root

After a successful sudo, it remembers you for 15 minutes in that terminal. That is why the second sudo in a row usually does not ask. sudo -k makes it forget immediately.

sudo !! re-runs the previous command with sudo in front (!! = "the previous command", lesson 1.7). You will type it daily: run something, get Permission denied, sudo !!.

The redirection trap

sudo echo "hello" > /etc/motd      # Permission denied

(/etc/motd is the "message of the day" file shown at login.)

Nothing is wrong with sudo here. Remember from 1.5: the shell handles >, and it does so first, as you, before sudo even starts. You may not write in /etc, so it fails before echo ever runs. sudo made echo root; nobody made the > root.

The two fixes both make a root process do the writing:

echo "hello" | sudo tee /etc/motd          # tee runs as root and writes
echo "hello" | sudo tee -a /etc/motd       # -a appends instead of replacing
sudo sh -c 'echo "hello" > /etc/motd'      # the whole command line runs in a root shell

tee FILE copies whatever arrives on its stdin into FILE and to the screen (like a T-junction in a pipe). sh -c '...' starts a new shell that runs the quoted text - with sudo, that shell is root, so its > is root too.

tee also prints what it wrote; add > /dev/null when you don't want to see it.

Packages and apt

A package is an installable bundle: a program plus its files and a list of the other packages it needs (its dependencies). A package manager installs, upgrades and removes packages and keeps track of what came from where. Ubuntu's is apt.

apt downloads packages from repositories: servers run by Ubuntu that hold thousands of packages. Your box keeps a local list of what each repository offers.

The apt verbs:

All of them change the system, so they need sudo. The pair you run on any new box:

sudo apt update && sudo apt upgrade -y

&& means "only if the first succeeded". If the update fails (no network), the upgrade is skipped rather than running against stale lists.

Reading what apt is about to do

Ubuntu 26.04 ships apt 3, which prints a plan before it touches anything:

$ sudo apt install tree jq
Installing:
  jq  tree

Installing dependencies:
  libjq1  libonig5

Summary:
  Upgrading: 0, Installing: 4, Removing: 0, Not Upgrading: 7
  Download size: 403 kB
  Space needed: 1,213 kB / 10.7 GB available

Continue? [Y/n]

Read the plan, especially any REMOVING: block (apt 3 prints it last, in red). apt only asks when it pulls in packages you did not name. Older Ubuntu and apt-get (the older, script-friendly front end to the same system) print the classic wording instead: "The following NEW packages will be installed", "0 upgraded, 4 newly installed...". Same information.

What you can now do

Ubuntu 25.10 and newer use sudo-rs: its password prompt reads [sudo: authenticate] Password: instead of [sudo] password for <user>:.

Why it helps

Package and permission mistakes are daily friction on a platform team. "Unable to locate package" is almost always a missing apt update. A setup script that writes a settings file with sudo echo ... > fails every time, and | sudo tee is the fix you will write into scripts and runbooks.

Knowing that sudo logs every command also matters: on a shared server, the log of who ran what as root is how you find out who changed a setting. And why root has no password on Ubuntu, and why you borrow root per command instead of logging in as root, are classic "how do you manage access" interview questions.

Commands in this lesson

whoami echo apt

FAQ

What is the difference between apt and apt-get?

Both use the same package database. apt is the friendlier front end for people at a keyboard: progress bars, colour, a readable plan, and extra commands like apt list and apt search. apt-get is the older one with output that never changes between versions, which makes it the safer choice inside scripts - apt itself warns that its output may change. Keyboard: apt. Scripts: apt-get.

Why does apt update not update anything?

Because it only refreshes the package lists: which versions of which packages the repositories currently offer. No installed software changes. apt upgrade then installs newer versions of packages you already have, using those lists. On a fresh box with empty or old lists, apt install x fails with "Unable to locate package" until you run apt update, which is why the two always travel together.

Is sudo su the same as sudo -i?

Both end with a root shell (a # prompt). sudo -i starts root's own login shell: $HOME is /root, root's settings are read, and you start in /root. sudo su runs su as root, which also gives a root shell but keeps more of your own environment. For a single command, plain sudo cmd is better: each command is logged individually, whereas inside a root shell nothing is.

What does autoremove actually remove?

Packages that were installed automatically, only because something else needed them, and that nothing needs any more. The big win on Ubuntu is old kernels: each kernel update leaves the previous one behind in /boot, which is small and can fill up. It never removes a package you installed by name yourself. Still, read its list before confirming.

Why does sudo tee print everything back to me?

tee copies its input to each file you name and also to stdout, the screen - that is its whole purpose in a pipeline. When you only want the file written, throw the copy away: echo x | sudo tee /etc/f > /dev/null. That redirection works without sudo because anyone may write to /dev/null. Use tee -a to append instead of replacing the file.

In an interview Junior

Why does sudo echo "x" > /etc/motd fail with Permission denied, and how do you fix it?

Because the redirection is done by your own shell, as you, before sudo even starts. The shell sees > /etc/motd and tries to open that file for writing as learner; only root may write in /etc, so it fails. sudo made echo root; nobody made the > root.

The fixes make a root process do the writing:

tee is the usual choice in written instructions because the quoting is simpler.

Also asked: What is the difference between apt update and apt upgrade, and why run update first? · Why use sudo instead of logging in as root? · What does apt autoremove clean up?

Practise this lesson in the terminal Free, in your browser - a real Ubuntu terminal to try it in, with missions that check your work.