Learn › RHCSA (EX200) › Operate Running Systems
systemctl - a hands-on Linux lab on a real virtual machine.
Tell a RHEL 10 machine which world to boot into with systemd targets. Read the default with systemctl get-default, change it persistently with set-default (the symlink at /etc/systemd/system/default.target the grader checks), list active targets, and know isolate for a live switch plus rescue and emergency for repair. Serves EX200 operating-systems task 12: boot systems into different targets manually.
A colleague hands you a server. It was supposed to come up as a plain text login on the console, the lean setup a server wants. Instead it boots into a full graphical desktop, burning memory on a screen no one will ever look at. Nothing is broken. It just wakes up as the wrong kind of machine every single time it reboots.
The fix is not a package to remove or a service to kill. It is one setting that decides which world the machine boots into. In systemd that setting is the default target, and changing it is EX200 operating-systems task 12: boot systems into different targets. By the end of this lesson you will read the current target, change it so the change survives every reboot, and know the exact symlink the exam grader inspects.
The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches. The outputs shown are from a real RHEL 10 machine (AlmaLinux 10.2). The commands you type here only READ the machine's state. The commands that CHANGE the running system or reboot it are described, never run live, so nothing you do in this lesson can disconnect you.
On a RHEL system, systemd is the first program the kernel starts. It has process ID 1, and everything else on the machine is a child of it. Its job is to bring the system up to a known state by starting the right set of services in the right order.
A target is a name for one of those states. Think of it as a saved scene. multi-user.target is the scene where the network is up, logins work, and services run, but there is no graphical desktop. graphical.target is that same scene plus the desktop on top. When the machine boots, systemd picks one target as the goal and starts every service that target needs to reach it.
The machine has to boot into SOME state, so systemd keeps a single pointer called the default target. That one pointer is the answer to which scene do I bring this machine up to. Change the pointer and you change what every future boot looks like.
Two commands cover the whole objective. systemctl get-default reads the pointer and tells you the current default. systemctl set-default moves the pointer to a target you name. Everything in this lesson is those two verbs, get and set, plus knowing which target names to hand them.
Start by asking the machine which world it boots into today. systemctl get-default prints the name of the default target and nothing else. Before you run it, make a call: this is a server image, so the sensible default is the text state, multi-user.target, not the graphical one.
Run the read:
systemctl get-default
prompt: student@servera:~$ answer: systemctl get-default output: multi-user.target hint: One word after systemctl, the verb that reads the default: systemctl get-default
multi-user.target. That is the text-mode server state: network up, logins and services running, no graphical desktop eating memory. This is the default RHEL 10 servers ship with, and it is the target the exam almost always wants a server left in. You just read the pointer; next you will look at what that target actually pulls in.
A freshly installed server prints multi-user.target here, but a machine someone set up as a desktop prints graphical.target. The command is the same on every machine. The exact target it names is whatever that machine was last set to, which is exactly the thing you are learning to control.
Targets are units, just like services, so you can list them with systemctl. systemctl list-units --type target shows the targets that are currently active, the layers systemd walked through to bring the machine up. You will see sysinit.target (early initialization), basic.target (the base layer), and multi-user.target (the full running server) among them.
List the active targets:
systemctl list-units --type target
prompt: student@servera:~$ answer: systemctl list-units --type target output: basic.target loaded active active Basic System multi-user.target loaded active active Multi-User System sysinit.target loaded active active System Initialization hint: The list verb, then narrow it to one kind of unit with --type target: systemctl list-units --type target
Three of the targets that stack up to a running server. sysinit.target runs the earliest setup, basic.target builds on it, and multi-user.target sits on top as the full text-mode state. They are layers, each depending on the one below. The real screen prints a few more lines than shown here, but these three are the backbone, and multi-user.target is the one you point the default at.
The exact set of active targets varies by machine and by what services are installed, so your list may be longer. The stack itself, sysinit then basic then multi-user, is the same on every RHEL system. That layering is the lesson; the precise line count is not.
A target is not empty. It is a bundle of dependencies: the services it wants started before it counts itself reached. You can count them. systemctl show multi-user.target -p Wants lists the units this target wants, and piping that into a word count shows just how much rides on a single target name.
The captured machine wants 17 units under multi-user.target. Run the show and read the number for yourself:
systemctl show multi-user.target -p Wants | tr ' ' '\n' | grep -c .service
prompt: student@servera:~$ answer: systemctl show multi-user.target -p Wants | tr ' ' '\n' | grep -c .service output: 17 hint: show the Wants property, split it onto one line each with tr, then grep -c to count the .service lines.
17. One target name stands in for seventeen services the machine must start to call itself multi-user. That is the power of a target: you point the default at one name, and systemd pulls in the whole bundle behind it. This is why changing the default target changes the entire character of the boot, not just one service.
The count is 17 on this image; a machine with more services installed wants more, and a leaner one wants fewer. The point is not the exact number. It is that a target is a bundle, so setting the default target sets the whole set of services the boot brings up.
Reading the pointer is half the job. The task is to CHANGE it so the change survives a reboot, and that is systemctl set-default. Because it writes system configuration, it needs root, so you run it with sudo. You hand it a target name and it repoints the default at that target.
Here is the shape you would run to pin a server to text mode:
sudo systemctl set-default multi-user.target
Under the hood, set-default does one small, precise thing: it replaces the symlink at /etc/systemd/system/default.target so it points at the target you named. That symlink IS the default. Because it lives on disk, it survives reboots, which is why the change is persistent, and it is the exact file the exam grader inspects to score task 12. Setting it with set-default and confirming with get-default is the whole objective.
Set the default only to multi-user.target or graphical.target. Never run sudo systemctl set-default rescue.target or emergency.target. Those are repair states, and if you make one the default, every reboot drops to a maintenance prompt that demands the root password, leaving a machine that cannot boot to a normal login. The exam wants a working default, so keep it multi-user or graphical.
set-default changes the NEXT boot. To change the state of the system RIGHT NOW without rebooting, the command is systemctl isolate, as in sudo systemctl isolate multi-user.target. It moves the live machine to that target immediately. It is described here rather than run, because isolating a state can drop services out from under an SSH session.
Two targets exist purely for repair, and you reach them when a machine will not boot normally:
You do not set these as the default. You reach them for ONE boot, either by systemctl isolate on a running system or by editing the kernel line at the GRUB menu and appending systemd.unit=rescue.target, then booting that once. The next reboot goes back to the real default.
rescue.target gives you a fuller environment: disks mounted, so you can edit files across the system. emergency.target is the barest possible shell with only the root filesystem read-only, which is what you want when the thing that is broken is the mounting itself. Both ask for the root password before they hand you the prompt.
Scaffolding off. No command is printed this time. You have every piece you need.
You have just walked up to an unfamiliar RHEL 10 server and you need to know one thing before you touch anything: which target does this machine boot into by default? You do not want to change it, only to read it. Recall the verb that reads the default pointer and prints its name.
prompt: student@servera:~$ answer: systemctl get-default output: multi-user.target hint: One systemctl subcommand reads the default and prints only its name. It is the read half of the get / set pair.
multi-user.target. get-default read the pointer and printed the one target this machine boots into, the text-mode server state. That single read is where every target task starts: you check what the default is now, decide what it should be, and only then reach for sudo systemctl set-default to move it. Read first, change second, and confirm with a second get-default. That is task 12 end to end.
You earned this cheat sheet. Every row is a form you just ran or read about:
The one idea to burn in for the exam: set-default changes the NEXT boot and persists because it writes a symlink on disk; isolate changes the state RIGHT NOW and does not persist. Task 12 is the persistent one, so it is set-default, then get-default to confirm.
Target names always end in .target, and you can shorten typing with tab completion: type systemctl set-default multi and press Tab to fill in multi-user.target. The full name matters, because set-default multiuser (no hyphen) fails with Failed to set default target, and on the exam a mistyped target is a lost point.
The practice terminal has shown you the shape of systemd targets: get-default to read the boot pointer, set-default to move it and make the change persist through the symlink at /etc/systemd/system/default.target, list-units --type target to see the layers, and the difference between the persistent set-default and the immediate isolate, plus the two rescue states you reach for one boot only. Every read command you typed yourself.
The operating-systems module mission is where you run these against a real RHEL 10 machine. A full VM boots for you, with its own default target to read and change. The mission hands you objectives that use exactly what you practiced here: check the current target, set a new default so it survives a reboot, and confirm the symlink is correct. One difference from this lesson: the mission shows no commands. You read the objective, recall the set-default and the get-default, and type them. That recall is what makes it stick on exam day.
Finish the other operating-systems lessons, then go tell a real machine which world to boot into.
Practice Boot into Different Targets in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.