|
| 1 | +--- |
| 2 | +author: |
| 3 | + name: Linode |
| 4 | + email: docs@linode.com |
| 5 | +description: 'This guide will cover how to use `systemctl` to manage systemd services.' |
| 6 | +keywords: ['systemctl','systemd','service','unit file','target'] |
| 7 | +license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' |
| 8 | +published: 2018-08-31 |
| 9 | +modified: 2018-08-31 |
| 10 | +modified_by: |
| 11 | + name: Linode |
| 12 | +title: "Introduction to systemctl" |
| 13 | +contributor: |
| 14 | + name: Linode |
| 15 | +external_resources: |
| 16 | +- '[Systemctl man page](https://www.freedesktop.org/software/systemd/man/systemctl.html)' |
| 17 | +- '[Creating and modifying systemd unit files](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files)' |
| 18 | +- '[Working with systemd targets](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-targets)' |
| 19 | +--- |
| 20 | + |
| 21 | +## What is systemctl? |
| 22 | + |
| 23 | +`systemctl` is a controlling interface and inspection tool for the widely-adopted init system and service manager systemd. This guide will cover how to use `systemctl` to manage systemd services, work with systemd Targets and extract meaningful information about your system's overall state. |
| 24 | + |
| 25 | +{{< note >}} |
| 26 | +This guide is written for a non-root user. Commands that require elevated privileges are prefixed with `sudo`. If you’re not familiar with the `sudo` command, see the [Users and Groups](/docs/tools-reference/linux-users-and-groups/) guide. |
| 27 | +{{< /note >}} |
| 28 | + |
| 29 | +## Managing Services |
| 30 | + |
| 31 | +`systemd` initializes *user space* components that run after the Linux kernel has booted, as well as continuously maintaining those components throughout a system's lifecycle. These tasks are known as *units*, and each unit has a corresponding *unit file*. Units might concern mounting storage devices (.mount), configuring hardware (.device), sockets (.socket), or, as will be covered in this guide, managing services (.service). |
| 32 | + |
| 33 | +### Starting and Stopping a Service |
| 34 | + |
| 35 | +To start a `systemd` service in the current session, issue the `start` command: |
| 36 | + |
| 37 | + sudo systemctl start apache2.service |
| 38 | + |
| 39 | +Conversely, to stop a `systemd` service, issue the `stop` command: |
| 40 | + |
| 41 | + sudo systemctl stop apache2.service |
| 42 | + |
| 43 | +In the above example we started and then stopped the Apache service. It is important to note that `systemctl` does not require the `.service` extension when working with service units. The following is just as acceptable: |
| 44 | + |
| 45 | + sudo systemctl start apache2 |
| 46 | + |
| 47 | +If the service needs to be restarted, such as to reload a configuration file, you can issue the `restart` command: |
| 48 | + |
| 49 | + sudo systemctl restart apache2 |
| 50 | + |
| 51 | +Similarly, if a service does not need to restart to reload it's configuration, you can issue the `reload` command: |
| 52 | + |
| 53 | + sudo systemctl reload apache2 |
| 54 | + |
| 55 | +Finally, you can use the `reload-or-restart` command if you are unsure about whether your application needs to be restarted or just reloaded. |
| 56 | + |
| 57 | + sudo systemctl reload-or-restart apache2 |
| 58 | + |
| 59 | +### Enabling a Service at Boot |
| 60 | + |
| 61 | +The above commands are good for managing a service in a single session, but many services are also required to start at boot. To enable a service at boot: |
| 62 | + |
| 63 | + sudo systemctl enable nginx |
| 64 | + |
| 65 | +Enabling a service creates a symlink from the unit file's location, usually in `/lib/systemd/system/` or `/etc/systemd/system`, to wherever `systemd` looks for autostart files (usually `/etc/systemd/system/yourservice.target.wants`, where `yourservice` is the name of the service). For more on targets, see [Working with systemd Targets](#working-with-systemd-targets). |
| 66 | + |
| 67 | +To disable the service from starting at boot, issue the `disable` command: |
| 68 | + |
| 69 | + sudo systemctl disable nginx |
| 70 | + |
| 71 | +{{< note >}} |
| 72 | +The `enable` command does not start the service in the current session, nor does `disable` stop the service in the current session. To enable/disable and start/stop a service simultaneously, combine the command with the `--now` switch: |
| 73 | + |
| 74 | + sudo systemctl enable nginx --now |
| 75 | +{{</ note >}} |
| 76 | + |
| 77 | +If the service unit file is not located within one of the known `systemd` file paths, you can provide a file path to the service unit file you wish to enable: |
| 78 | + |
| 79 | + sudo systemctl enable /path/to/myservice.service |
| 80 | + |
| 81 | +However, this file needs to be accessible by `systemd` at startup. For example, this means files underneath `/home` or `/var` are not allowed, unless those directories are located on the root file system. |
| 82 | + |
| 83 | +### Checking a Service's Status |
| 84 | + |
| 85 | +`systemctl` allows us to check on the status of individual services: |
| 86 | + |
| 87 | + systemctl status mysql |
| 88 | + |
| 89 | +This will result in a message similar to the output below: |
| 90 | + |
| 91 | +{{< output >}} |
| 92 | + ● mysql.service - MySQL Community Server |
| 93 | + Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) |
| 94 | + Active: active (running) since Thu 2018-08-30 09:15:35 EDT; 1 day 5h ago |
| 95 | + Main PID: 711 (mysqld) |
| 96 | + Tasks: 31 (limit: 2319) |
| 97 | + CGroup: /system.slice/mysql.service |
| 98 | + └─711 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid |
| 99 | +{{</ output >}} |
| 100 | + |
| 101 | +You can also use `is-active`, `is-enabled`, and `is-failed` to monitor a service's status: |
| 102 | + |
| 103 | + systemctl is-enabled mysql |
| 104 | + |
| 105 | +To view which `systemd` service units are currently active on your system, issue the following `list-units` command and filter by the service type: |
| 106 | + |
| 107 | + systemctl list-units --type=service |
| 108 | + |
| 109 | +{{< note >}} |
| 110 | +`list-units` is the default action for the `systemctl` command, so you can simply enter `systemctl` to retrieve a list of units. |
| 111 | +{{</ note >}} |
| 112 | + |
| 113 | +The generated list includes all currently active service units, service units that have jobs pending, and service units that were active and have failed: |
| 114 | + |
| 115 | + UNIT LOAD ACTIVE SUB DESCRIPTION |
| 116 | + accounts-daemon.service loaded active running Accounts Service |
| 117 | + apparmor.service loaded active exited AppArmor initialization |
| 118 | + apport.service loaded active exited LSB: automatic crash report generation |
| 119 | + atd.service loaded active running Deferred execution scheduler |
| 120 | + blk-availability.service loaded active exited Availability of block devices |
| 121 | + console-setup.service loaded active exited Set console font and keymap |
| 122 | + cron.service loaded active running Regular background program processing daemon |
| 123 | + dbus.service loaded active running D-Bus System Message Bus |
| 124 | + ebtables.service loaded active exited ebtables ruleset management |
| 125 | + ... |
| 126 | + |
| 127 | +The output provides five pieces of data: |
| 128 | + |
| 129 | +- **UNIT**: The name of the unit. |
| 130 | +- **LOAD**: Was the unit properly loaded? |
| 131 | +- **ACTIVE**: The general activation state, i.e. a generalization of SUB. |
| 132 | +- **SUB**: The low-level unit activation state, with values dependent on unit type. |
| 133 | +- **DESCRIPTION**: The unit's description. |
| 134 | + |
| 135 | +To list all units, including inactive units, append the `--all` flag: |
| 136 | + |
| 137 | + systemctl list-units --type=service --all |
| 138 | + |
| 139 | +You can filter the list of units by state. Supply a comma-separated list of unit states to output as the value for the `--state` flag: |
| 140 | + |
| 141 | + systemctl list-units --type=service --all --state=exited,inactive |
| 142 | + |
| 143 | +To retrieve a list of failed units, enter the `list-units` command with the `--failed` flag: |
| 144 | + |
| 145 | + systemctl list-units --failed |
| 146 | + |
| 147 | +## Working with Unit Files |
| 148 | + |
| 149 | +Each unit has a corresponding *unit file*. These unit files are usually located in the following directories: |
| 150 | + |
| 151 | +- The `/lib/systemd/system` directory holds unit files that are provided by the system or are supplied by installed packages. |
| 152 | +- The `/etc/systemd/system` directory stores unit files that are user-provided. |
| 153 | + |
| 154 | +### Listing Installed Unit Files |
| 155 | + |
| 156 | + Not all unit files are active on a system at any given time. To view all `systemd` service unit files installed on a system, use the `list-unit-files` command with the optional `--type` flag: |
| 157 | + |
| 158 | + systemctl list-unit-files --type=service |
| 159 | + |
| 160 | +The generated list has two columns, **UNIT FILE** and **STATE**: |
| 161 | + |
| 162 | + UNIT FILE STATE |
| 163 | + accounts-daemon.service enabled |
| 164 | + acpid.service disabled |
| 165 | + apparmor.service enabled |
| 166 | + apport-forward@.service static |
| 167 | + apt-daily-upgrade.service static |
| 168 | + apt-daily.service static |
| 169 | + ... |
| 170 | + |
| 171 | +A unit's STATE can be either enabled, disabled, static, masked, or generated. Unit files with a static state do not contain an *Install* section and are either meant to be run once or they are a dependency of another unit file and should not be run alone. For more on masking, see [Masking a Unit File](#masking-a-unit-file). |
| 172 | + |
| 173 | +### Viewing a Unit File |
| 174 | + |
| 175 | +To view the contents of a unit file, run the `cat` command: |
| 176 | + |
| 177 | + systemctl cat cron |
| 178 | + |
| 179 | +{{< output >}} |
| 180 | +# /lib/systemd/system/cron.service |
| 181 | +[Unit] |
| 182 | +Description=Regular background program processing daemon |
| 183 | +Documentation=man:cron(8) |
| 184 | + |
| 185 | +[Service] |
| 186 | +EnvironmentFile=-/etc/default/cron |
| 187 | +ExecStart=/usr/sbin/cron -f $EXTRA_OPTS |
| 188 | +IgnoreSIGPIPE=false |
| 189 | +KillMode=process |
| 190 | + |
| 191 | +[Install] |
| 192 | +WantedBy=multi-user.target |
| 193 | +{{</ output >}} |
| 194 | + |
| 195 | +If there are recent changes to the unit file that have not yet been loaded into systemd, the output of the `systemctl cat` command may be an older version of the service. |
| 196 | + |
| 197 | +For a low-level view of a unit file, issue the `show` command: |
| 198 | + |
| 199 | + systemctl show cron |
| 200 | + |
| 201 | +This will generate a list of property key=value pairs for all non-empty properties defined in the unit file: |
| 202 | + |
| 203 | + Type=simple |
| 204 | + Restart=no |
| 205 | + NotifyAccess=none |
| 206 | + RestartUSec=100ms |
| 207 | + TimeoutStartUSec=1min 30s |
| 208 | + TimeoutStopUSec=1min 30s |
| 209 | + RuntimeMaxUSec=infinity |
| 210 | + ... |
| 211 | + |
| 212 | +To show empty property values, supply the `--all` flag. |
| 213 | + |
| 214 | +To filter the key=value pairs by property, use the `-p` flag: |
| 215 | + |
| 216 | + systemctl show cron -p Names |
| 217 | + |
| 218 | +Note that the property name must be capitalized. |
| 219 | + |
| 220 | +### Viewing a Unit File's Dependencies |
| 221 | + |
| 222 | +To display a list of a unit file's dependencies, use the `list-dependencies` command: |
| 223 | + |
| 224 | + systemctl list-dependencies cron |
| 225 | + |
| 226 | +The generated output will show a tree of unit dependencies that must run before the service in question runs. |
| 227 | + |
| 228 | + cron.service |
| 229 | + ● ├─system.slice |
| 230 | + ● └─sysinit.target |
| 231 | + ● ├─apparmor.service |
| 232 | + ● ├─blk-availability.service |
| 233 | + ● ├─dev-hugepages.mount |
| 234 | + ● ├─dev-mqueue.mount |
| 235 | + ● ├─friendly-recovery.service |
| 236 | + ... |
| 237 | + |
| 238 | +Recursive dependencies are only listed for `.target` files. To list all recursive dependencies, pass in the `--all` flag. |
| 239 | + |
| 240 | +To check which unit files depend on a service unit file, you can run the `list-dependencies` command with the `--reverse` flag: |
| 241 | + |
| 242 | + systemctl list-dependencies cron --reverse |
| 243 | + |
| 244 | +### Editing a Unit File |
| 245 | + |
| 246 | +{{< note >}} |
| 247 | +While the particulars of unit file contents are beyond the scope of this article, there are a number of good resources online that describe them, such as the RedHat Customer Portal page on [Creating and Modifying systemd Unit Files](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files). |
| 248 | +{{</ note >}} |
| 249 | + |
| 250 | +There are two ways to edit a unit file using `systemctl`. |
| 251 | + |
| 252 | +1. The `edit` command opens up a blank drop-in snippet file in the system's default text editor: |
| 253 | + |
| 254 | + sudo systemctl edit ssh |
| 255 | + |
| 256 | + When the file is saved, `systemctl` will create a file called `override.conf` under a directory at `/etc/systemd/system/yourservice.service.d`, where `yourservice` is the name of the service you chose to edit. This command is useful for changing a few properties of the unit file. |
| 257 | + |
| 258 | +2. The second way is to use the `edit` command with the `--full` flag: |
| 259 | + |
| 260 | + sudo systemctl edit ssh --full |
| 261 | + |
| 262 | + This command opens a full copy of whatever unit file you chose to edit in a text editor. When the file is saved, `systemctl` will create a file at `/etc/systemd/system/yourservice.service`. This is useful if you need to make many changes to an existing unit file. |
| 263 | + |
| 264 | +In general, any unit file in `/etc/systemd/system` will override the corresponding file in `/lib/systemd/system`. |
| 265 | + |
| 266 | +### Creating a Unit File |
| 267 | + |
| 268 | +While `systemctl` will throw an error if you try to open a unit file that does not exist, you can force `systemctl` to create a new unit file using the `--force` flag: |
| 269 | + |
| 270 | + sudo systemctl edit yourservice.service --force |
| 271 | + |
| 272 | +When the file is saved, `systemctl` will create an `override.conf` file in the `/etc/systemd/system/yourservice.service.d` directory, where 'yourservice' is the name of the service you chose to create. To create a full unit file instead of just a snippet, use `--force` in tandem with `--full`: |
| 273 | + |
| 274 | + sudo systemctl edit yourservice.service --force --full |
| 275 | + |
| 276 | +### Masking a Unit File |
| 277 | + |
| 278 | +To prevent a service from ever starting, either manually or automatically, use the `mask` command to symlink a service to `/dev/null`: |
| 279 | + |
| 280 | + sudo systemctl mask mysql |
| 281 | + |
| 282 | +Similar to disabling a service, the `mask` command will not prevent a service from continuing to run. To mask a service and stop the service at the same time, use the `--now` switch: |
| 283 | + |
| 284 | + sudo systemctl mask mysql --now |
| 285 | + |
| 286 | +To unmask a service, use the `unmask` command: |
| 287 | + |
| 288 | + sudo systemctl unmask mysql |
| 289 | + |
| 290 | +### Removing a Unit File |
| 291 | + |
| 292 | +To remove a unit file snippet that was created with the `edit` command, remove the directory `yourservice.service.d` (where 'yourservice' is the service you would like to delete), and the `override.conf` file inside of the directory: |
| 293 | + |
| 294 | + sudo rm -r /etc/systemd/system/yourservice.service.d |
| 295 | + |
| 296 | +To remove a full unit file, run the following command: |
| 297 | + |
| 298 | + sudo rm /etc/systemd/system/yourservice.service |
| 299 | + |
| 300 | +After you issue these commands, reload the `systemd` daemon so that it no longer tries to reference the deleted service: |
| 301 | + |
| 302 | + sudo systemctl daemon-reload |
| 303 | + |
| 304 | +## Working with systemd Targets |
| 305 | + |
| 306 | +`systemd` targets are represented by *target units*. Target units end with the `.target` file extension and their only purpose is to group together other systemd units through a chain of dependencies. Like other init system's run levels, these targets help `systemd` determine which unit files are necessary to produce a certain system state. |
| 307 | + |
| 308 | +For instance, there is a `graphical.target` that denotes when the system's graphical session is ready. Units that are required to start in order to achieve the necessary state have `WantedBy=` or `RequiredBy=` `graphical.target` in their configuration. Units that depend on `graphical.target` can include `Wants=`, `Requires=`, or `After=` in their configuration to make themselves available at the correct time. |
| 309 | + |
| 310 | +### Getting and Setting the Default Target |
| 311 | + |
| 312 | +To get the default target for your system --the end goal of the chain of dependencies-- issue the `get-default` command: |
| 313 | + |
| 314 | + systemctl get-default |
| 315 | + |
| 316 | +If you would like to change the default target for your system, issue the `set-default` command: |
| 317 | + |
| 318 | + sudo systemctl set-default multi-user.target |
| 319 | + |
| 320 | +### Listing Targets |
| 321 | + |
| 322 | +To retrieve a list of available targets, use the `list-unit-files` command and filter by target: |
| 323 | + |
| 324 | + systemctl list-unit-files --type=target |
| 325 | + |
| 326 | +To list all currently active targets, use the `list-units` command and filter by target: |
| 327 | + |
| 328 | + systemctl list-units --type=target |
| 329 | + |
| 330 | +### Changing the Active Target |
| 331 | + |
| 332 | +To change the current active target, issue the `isolate` command. This command starts the isolated target with all dependent units and shuts down all others. For instance, if you wanted to move to a multi-user command line interface and stop the graphical shell, use the following command: |
| 333 | + |
| 334 | + sudo systemctl isolate multi-user.target |
| 335 | + |
| 336 | +However, it is a good idea to first check on the dependencies of the target you wish to isolate so you do not stop anything important. To do this, issue the `list-dependencies` command: |
| 337 | + |
| 338 | + systemctl list-dependencies multi-user.target |
| 339 | + |
| 340 | +### Rescue Mode |
| 341 | + |
| 342 | +When a situation arises where you are unable to proceed with a normal boot, you can place your system in rescue mode. Rescue mode provides a single-user interface used to repair your system. To place your system in rescue mode, enter the following command: |
| 343 | + |
| 344 | + sudo systemctl rescue |
| 345 | + |
| 346 | +This command is similar to `systemctl isolate rescue`, but will also issue a notice to all other users that the system is entering rescue mode. To prevent this message from being sent, apply the `--no-wall` flag: |
| 347 | + |
| 348 | + sudo systemctl rescue --no-wall |
| 349 | + |
| 350 | +### Emergency Mode |
| 351 | + |
| 352 | +Emergency mode offers the user the most minimal environment possible to salvage a system in need of repair, and is useful if the system cannot enter rescue mode. For a full explanation of emergency mode, refer to the [RedHat Customer Portal page](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-targets#sect-Managing_Services_with_systemd-Targets-Emergency). To enter emergency mode, enter the following command: |
| 353 | + |
| 354 | + sudo systemctl emergency |
| 355 | + |
| 356 | +This command is similar to `systemctl isolate emergency`, but will also issue a notice to all other users that the system is entering emergency mode. To prevent this message, apply the `--no-wall` flag: |
| 357 | + |
| 358 | + sudo systemctl emergency --no-wall |
| 359 | + |
| 360 | +### More Shortcuts |
| 361 | + |
| 362 | +`systemctl` allows users the ability to halt, shutdown and reboot a system. |
| 363 | + |
| 364 | +To halt a system, issue the following command: |
| 365 | + |
| 366 | + sudo systemctl halt |
| 367 | + |
| 368 | +To shutdown a system, use: |
| 369 | + |
| 370 | + sudo systemctl shutdown |
| 371 | + |
| 372 | +Finally, to reboot a system, enter the following command: |
| 373 | + |
| 374 | + sudo systemctl reboot |
| 375 | + |
| 376 | +Similar to the `emergency` and `rescue` commands, these commands will issue a notice to all users that the system state is changing. |
0 commit comments