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:
apt update- refresh the local lists of what exists in the repositories. Installs nothing. Skipping it is why "Unable to locate package" happens on a fresh box - the lists are empty or stale.apt upgrade- install newer versions of the packages you already have.apt install X- install package X and its dependencies.apt autoremove- delete dependencies nothing needs any more. Old kernels pile up in/boot(where the boot files live) and this is what clears them.-yanswers "yes" to the confirmation question in advance.
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]
- Installing - what you asked for.
- Installing dependencies - what those need (
lib...packages are libraries: shared code other programs use). - Summary - counts, how much will download, how much disk it takes.
[Y/n]- the capital letter is the default if you just press Enter.
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
- Run one command as root with
sudo, and know why the password is yours. - Write to a root-owned file with
| sudo teeinstead ofsudo ... >. - Refresh, upgrade and install packages, and read apt's plan before saying yes.