LPIC-1 Essential Services: Localization, Mail Basics, and Printing
- Set the system time zone and reason about how LANG, the LC_* categories, and LC_ALL override one another
- Redirect local mail with /etc/aliases (and newaliases) or a personal ~/.forward, and read the mail queue
- Submit, list, and remove print jobs in CUPS using both the System V and BSD command families
- Avoid the three classic exam traps: forgetting newaliases, expecting LANG to beat LC_ALL, and mixing the two print families
Why "essential services" hang together
Frame localization, mail, and printing as the three sysadmin chores every host eventually needs.
LPIC-1 groups three unrelated-looking chores under "essential services" because every real server eventually has to do all three: tell time in the right time zone and language (localization), deliver mail that programs like
cronand monitoring tools generate, and print (still true in offices, labs, and point-of-sale).Think of a freshly installed server as a new employee on their first day. Before they're useful you set their desk clock to the local time, tell them which language to file reports in, point their inbox at the right person, and show them where the printer is. That's localization, mail aliasing, and CUPS — exactly this lesson.
The exam doesn't test deep theory here; it tests whether you know the one command that makes a change take effect and the override order when settings conflict. Those are precisely where people lose easy points.
Localization: time zone and the zoneinfo database
Set the system time zone and know where the zone data lives.
A server logs events in its local time zone, so getting the zone wrong corrupts every timestamp in correlation and forensics. On a systemd host,
timedatectlis the single tool that reads and writes the clock, the zone, and NTP sync status.The list of valid zones isn't magic — it's a directory of files under `/usr/share/zoneinfo`, organized as
Region/City(for exampleAmerica/New_York,Europe/London). Setting a zone just points/etc/localtimeat the matching file in that tree.timedatectlLocal time: Tue 2026-06-23 14:02:10 UTC Universal time: Tue 2026-06-23 14:02:10 UTC RTC time: Tue 2026-06-23 14:02:10 Time zone: Etc/UTC (UTC, +0000) System clock synchronized: yes NTP service: activeRun with no arguments, timedatectlprints the full clock report. The `Time zone:` line is the one to read first — here the host is onEtc/UTC.System clock synchronized: yesconfirms NTP is keeping the clock accurate, which matters because a drifting clock breaks log correlation and TLS.sudo timedatectl set-timezone America/New_York- set-timezone
- Point the system clock at a Region/City zone from /usr/share/zoneinfo and update /etc/localtime.
- set-time
- Manually set the wall-clock time (only works when NTP sync is off).
- set-ntp
- Turn automatic network time synchronization on or off (set-ntp true|false).
Success is silent — no output means it worked. The argument must be an exact Region/Citystring that exists under/usr/share/zoneinfo; a typo likeAmerica/NewYorkfails. Verify withtimedatectlagain and theTime zone:line will now readAmerica/New_York.Check yourself
Which directory holds the time-zone data files that timedatectl chooses from?
Localization: LANG, the LC_* categories, and LC_ALL
Master the locale override order — the single most testable point in localization.
A locale controls language and cultural formatting: the language of messages, how dates and numbers are written, currency symbols, and sort order. Linux splits these into categories, each its own variable:
LC_TIME(date/time format),LC_NUMERIC(decimal point vs. comma),LC_MESSAGES(program-message language),LC_COLLATE(sort order), and more.Three levels decide what actually applies, and the override order is the whole point:
- `LANG` is the default for every category. Set it alone and everything follows it.
- An individual *`LC_
** variable *overridesLANG`* for just its one category. - `LC_ALL` is the sledgehammer: it overrides
LANGand everyLC_*at once.
Think of it as "house rule, room rule, fire alarm."
LANGis the house rule everyone follows by default. AnLC_TIMEsetting is a room rule that wins inside that one room.LC_ALLis the fire alarm — when it sounds, every other rule is ignored and everyone does the one thing it says.localeLANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_ALL=
localewith no arguments shows the effective value of every category.LANGis set and everyLC_*is inheriting from it (shown in quotes). Crucially, `LC_ALL=` is empty — so nothing is overriding the rest. IfLC_ALLhad a value, every line above it would show that value instead, regardless ofLANG.LANG=en_US.UTF-8 LC_TIME=de_DE.UTF-8 LC_ALL=fr_FR.UTF-8 localeLANG=en_US.UTF-8 LC_CTYPE="fr_FR.UTF-8" LC_NUMERIC="fr_FR.UTF-8" LC_TIME="fr_FR.UTF-8" LC_COLLATE="fr_FR.UTF-8" LC_MESSAGES="fr_FR.UTF-8" LC_ALL=fr_FR.UTF-8
This is the override order made visible. We asked for LANG=en_US,LC_TIME=de_DE, andLC_ALL=fr_FRall at once. The result: every category is `fr_FR`.LC_ALLwon outright — evenLC_TIME, which was explicitly set to German, is forced to French.LANGis shown unchanged but it has no effect whileLC_ALLis set. RemoveLC_ALLandLC_TIMEwould become German while the rest fall back to English.Check yourself
LANG=en_US.UTF-8 and LC_ALL=de_DE.UTF-8 are both set. In which language do program messages appear?
Mail basics: the MTA, /etc/aliases, and ~/.forward
Redirect local mail two ways and know which one needs newaliases.
A Mail Transfer Agent (MTA) — Postfix, sendmail, exim — is the daemon that delivers mail to local mailboxes and relays it onward to other servers. Even a headless box runs one, because
cron, the system itself, and monitoring tools all send mail toroot.Nobody wants to log in as
rootto read those, so you redirect mail. There are two mechanisms, and knowing who controls which is the exam's angle:- `/etc/aliases` — the administrator's system-wide map. Each line is
name: target, e.g.root: webadmin. It redirects mail for any local recipient. - `~/.forward` — a file in a user's own home directory containing a destination address. A user forwards their own mail without needing root.
Runnable in the netsvc-postfix-relay room — that room’s setup plants the files it reads
grep -E '^(root|postmaster):' /etc/aliasespostmaster: root root: webadmin
- -E
- Extended regular expressions, so the (a|b) alternation works without backslashes.
The aliases file maps recipients to targets. Here mail to postmasterlands onroot, androot's mail is then forwarded towebadmin— so a real human reads it. Aliases can chain (postmaster → root → webadmin) and a target can be a user, another alias, a file, or a|commandpipe.Example — not runnable on your lab box
sudo newaliases/etc/aliases: 14 aliases, longest 18 bytes, 210 bytes total
newaliasesrecompiles/etc/aliasesinto/etc/aliases.dband reports how many aliases it processed. Now the changes are live. Run this every single time you touch the aliases file.For a single user,
~/.forwardis simpler and needs no admin and no rebuild step. The user just drops a destination into the file in their home directory:echo 'webadmin@example.com' > ~/.forwardThis one line forwards all of the current user's incoming local mail to webadmin@example.com. Nonewaliasesis needed — the MTA reads~/.forwardlive at delivery time. To keep a local copy as well as forward, the file would list both\username(the backslash means "deliver locally") and the external address.Example — not runnable on your lab box
mailqMail queue is empty
mailq(equivalentlysendmail -bp) shows mail the MTA has accepted but not yet delivered — typically because the remote server is down. An empty queue is healthy. A growing queue means delivery is stalling and is worth investigating. The plainmailcommand, by contrast, reads your inbox and sends new messages.Check yourself
You added 'root: webadmin' to /etc/aliases but root's mail still isn't reaching webadmin. What command did you most likely forget?
- `/etc/aliases` — the administrator's system-wide map. Each line is
Printing with CUPS: two command families
Submit, list, and remove print jobs — and keep the System V and BSD commands straight.
CUPS (the Common Unix Printing System) is the print service on modern Linux. It runs as a daemon, maintains a queue per printer, and accepts jobs over the network or locally.
The twist that the exam loves: there are two parallel command sets that do the same things, inherited from Unix history:
- System V family:
lp(submit),lpstat(status),cancel(remove). - BSD family:
lpr(submit),lpq(queue),lprm(remove).
Think of them as two languages for the same office: "submit / status / cancel" vs. "lpr / lpq / lprm." Both reach the same CUPS queue; you just have to recognize either dialect — and not mix a verb from one family expecting the other's syntax.
Adding and configuring printers is a separate, admin-only tool: `lpadmin`.
Example — not runnable on your lab box
sudo lpadmin -p office-laser -E -v ipp://printserver/printers/laser -m everywhere- -p
- Name of the printer queue to create or modify (here, office-laser).
- -E
- Enable the printer and accept jobs immediately.
- -v
- Device URI — where CUPS sends the data (here an IPP network printer).
- -m
- Driver/PPD model; 'everywhere' uses driverless IPP.
lpadminis the administrative tool that creates and configures printers; success is silent. After this,office-laserexists as a queue that thelp/lprcommands can target. Ordinary users never needlpadmin— they just submit to a printer an admin already set up.Example — not runnable on your lab box
lp -d office-laser report.pdfrequest id is office-laser-42 (1 file(s))
- -d
- Destination printer queue. Omit it and the job goes to the default printer.
- -n
- Number of copies (e.g. -n 3).
lp(System V) submitsreport.pdfto theoffice-laserqueue and prints the job idoffice-laser-42— note that id, you'll need it to cancel. The BSD equivalent islpr -P office-laser report.pdf(note-P, capital, instead of-d).Example — not runnable on your lab box
lpstat -tscheduler is running system default destination: office-laser device for office-laser: ipp://printserver/printers/laser office-laser accepting requests since Tue 23 Jun 2026 printer office-laser is idle. enabled since Tue 23 Jun 2026 office-laser-42 webadmin 4096 Tue 23 Jun 2026 02:11:00 PM
- -t
- Total status: scheduler state, default printer, every printer, and all queued jobs at once.
- -p
- Show printers and whether each is enabled.
lpstat -tis the one-stop status view: the scheduler is up,office-laseris the default and accepting jobs, and job `office-laser-42` (owned bywebadmin) is queued. The BSD equivalent for just the queue islpq -P office-laser, which lists the same job in a simpler table.Example — not runnable on your lab box
cancel office-laser-42cancel(System V) removes joboffice-laser-42from the queue; success is silent. The BSD equivalent islprm office-laser-42. Both delete the job —cancel/lprmare the remove pair, one per family.Check yourself
Which command removes a queued print job in the BSD family (the counterpart to System V's cancel)?
- System V family:
Try it in your live terminal
Do it, don't just read it — these are safe, read-only commands on the real sandbox to your right.
You have a real shell. These commands only read state — they change nothing — so run them freely and compare the output to what you learned above.
timedatectlRead the current clock and time zone. Find the Time zone:line — that's the settingset-timezonewould change.localectl status 2>/dev/null || localeShow the system locale. localectl statusreports it on systemd hosts; if that tool isn't present the fallbacklocalelists every category and whetherLC_ALLis set.localeList the effective value of LANG and every LC_* category. Confirm whether LC_ALLis empty — if it has a value, it is overriding everything above it.lpstat -t 2>/dev/null || echo 'CUPS not running'Show the CUPS scheduler, printers, and any queued jobs. If CUPS isn't installed or running on this sandbox, the fallback message prints instead — that's fine, the syntax is what matters.
- Locale precedence is the whole game: *LC_ALL > individual LC_ > LANG.** LC_ALL ignores everything else, so leave it unset in normal config.
timedatectl set-timezonesets the zone; valid zones live under/usr/share/zoneinfoas Region/City.- Editing
/etc/aliasesdoes nothing untilnewaliasesrebuilds the database;~/.forwardis per-user and needs no rebuild. - CUPS exposes two command families for the same actions — submit (
lp/lpr), status (lpstat/lpq), remove (cancel/lprm) — andlpuses-dwhilelpruses-P.
| Command or setting | Effect | Watch for |
|---|---|---|
timedatectl set-timezone Z | Set system time zone to zone Z | Z must exist under /usr/share/zoneinfo |
LANG / LC_* / LC_ALL | Locale defaults / per-category / force-all | LC_ALL overrides both LANG and every LC_* |
edit /etc/aliases + newaliases | System-wide mail redirect (admin) | No newaliases = change is silently ignored |
~/.forward | Per-user mail forward (self-service) | No rebuild needed; \user to also keep a local copy |
mailq | Show undelivered mail in the queue | A growing queue = delivery is stalling |
lp -d / lpr -P | Submit a print job (SysV / BSD) | lp uses -d, lpr uses -P — don't swap them |
lpstat/lpq, cancel/lprm | Show queue / remove job (SysV / BSD) | Same actions, two families — recognize both |
