Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use systemd to manage startup items

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to use systemd to manage startup items". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn how to use systemd to manage startup items.

Learn how systemd determines the order in which services are started, even if it is essentially a parallel system.

When setting up the Linux system recently, I wanted to know how to make sure that the dependencies between services and other units were up and running before the services and units that depended on them were up and running. I need more knowledge about how systemd manages the launcher, especially how the service startup order is determined in a system that is essentially parallel.

You may know that SystemV (the predecessor of systemd, which I explained in the first article in this series) determines the startup order by naming the startup script with the Sxx prefix, xx is a number from 00 to 99. SystemV then sorts by file name and executes each startup script in the queue according to the desired run level.

However, systemd uses unit files to define subroutines, which can be created or edited by your system administrator, and can be used not only for initialization but also for general operations. In the third article in this series, I explained how to create a mount unit file. In the fifth article, I explained how to create a different unit file-- a service unit file that executes a program at startup. You can also modify some configurations in the unit file, and then use the systemd log to see the location of your changes in the startup sequence.

Preparatory work

First make sure that you have removed rhgb and quiet from the GRUB_CMDLINE_LINUX= line in the / etc/default/grub file, as I showed in the second article in this series. This allows you to view the Linux startup information flow, which you need to use in some of the experiments in this article.

program

In this tutorial, you will create a simple program that allows you to view startup information in the console and subsequent systemd logs.

Create a shell program / usr/local/bin/hello.sh and add the following. You need to make sure that the execution result is visible at startup and can be easily found in the systemd log. You will use a version of the "Hello world" program with some squares, so it will be very conspicuous. To ensure that this file is executable, and for security reasons, it requires user and group ownership and 700permissions for root.

#! / usr/bin/bash# Simple program to use for testing startup configurations# with systemd.# By David Both# Licensed under GPL V2#echo "#" echo "# Hello World! #" echo "# #"

Execute the program on the command line to check whether it works properly.

[root@testvm1 ~] # hello.sh## Hello World! # # [root@testvm1 ~] #

This program can be implemented in any script or compiled language. Hello.sh programs can be placed anywhere on the Linux file system hierarchy (FHS). I put it in the / usr/local/bin directory so that it can be executed directly on the command line without having to take the path in front of the command. I find that many of the shell programs I create need to be run from the command line and other tools such as systemd.

Service unit file

Create the service unit file / etc/systemd/system/hello.service and write the following. This file is not necessarily executable, but for security reasons, it requires user and group ownership and 644 or 640 permissions for root.

# Simple service unit file to use for testing# startup configurations with systemd.# By David Both# Licensed under GPL V2# [Unit] Description=My hello shell script [Service] Type=oneshotExecStart=/usr/local/bin/hello.sh [Install] WantedBy=multi-user.target

Check the service status to confirm that the service unit file can run as scheduled. If there are any grammatical problems, errors will be displayed here.

[root@testvm1 ~] # systemctl status hello.service ● hello.service-My hello shell script Loaded: loaded (/ etc/systemd/system/hello.service; disabled; vendor preset: disabled) Active: inactive (dead) [root@testvm1 ~] #

You can run this "oneshot" type of service multiple times without a problem. Such services apply to services started by the service unit file that are the main process and must be completed before systemd starts any dependent processes.

There are seven service types, and you can find detailed explanations for each (and the rest of the service unit file) on the man page of systemd.service (5). You can also find more information in the material at the end of the article. )

Out of curiosity, I want to see what the mistake looks like. So I deleted the letter "o" from the Type=oneshot line, and now it looks like this Type=neshot, and now execute the command again:

[root@testvm1] # systemctl status hello.service ● hello.service-My hello shell script Loaded: loaded (/ etc/systemd/system/hello.service; disabled; vendor preset: disabled) Active: inactive (dead) May 06 08:50:09 testvm1.both.org systemd [1]: / etc/systemd/system/hello.service:12: Failed to parse service type, ignoring: neshot [root@testvm1 ~] #

The result of the execution clearly tells me where the error is, which makes it very easy to solve the error.

It is important to note that even after you save the hello.service file in its original form, the error still exists. Although rebooting the machine can eliminate this error, you don't have to, so I found a way to clean up such persistence errors. I've come across some errors that require the systemctl daemon-reload command to reset the error state, but it doesn't work in this case. Bugs that can be fixed with this command always seem to have such a declaration, so you know to run it.

However, it is recommended to perform systemctl daemon-reload after each modification or creation of a new unit file. It alerts systemd that changes have taken place, and it prevents certain problems related to management services or units. So go ahead and carry out this order.

After correcting the spelling errors in the service unit file, a simple systemctl restart hello.service command can clear the errors. Experiment and see what happens by adding some other errors to the hello.service file.

Start the service

Now you are ready to start the new service and check the status to see the results. Although you may have restarted before, you can still start or restart this single service any number of times, because it only runs once and then exits.

Continue to start the service (shown below), and then check the status. Your result may be different from mine, depending on how many trial and error experiments you have done.

[root@testvm1 ~] # systemctl start hello.service [root@testvm1 ~] # systemctl status hello.service ● hello.service-My hello shell script Loaded: loaded (/ etc/systemd/system/hello.service; disabled Vendor preset: disabled) Active: inactive (dead) May 10 10:37:49 testvm1.both.org hello.sh: # Hello World! # May 10 10:37:49 testvm1.both.org hello.sh: # # May 10 10:37:49 testvm1.both.org systemd [1 ]: hello.service: Succeeded.May 10 10:37:49 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10:54:45 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org hello .sh [1380]: # Hello World! # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:54:45 testvm1.both.org systemd [1]: Finished My hello shell script. [root@testvm1 ~] #

We can see from the output of the status check command that the systemd log indicates that hello.sh starts and the service ends. You can also see the output of the script. This output is generated based on the logging of recent calls to the service, try starting the service a few more times, and then look at the output of the status command to understand what I'm saying.

You should also check the contents of the log directly. There are many ways to do this. One way is to specify the record type identifier, which in this case is the name of the shell script. It shows the logging of previous restarts and the current session. As you can see, I have been doing research and testing for this article for a long time.

[root@testvm1] # journalctl-t hello.sh-- Reboot-- May 08 15:55:47 testvm1.both.org hello.sh: # # May 08 15:55:47 testvm1.both.org hello.sh: # Hello World! # May 08 15:55:47 testvm1.both Hello.sh: # #-- Reboot-- May 08 16:01:51 testvm1.both.org hello.sh: # # May 08 16:01:51 testvm1.both.org hello.sh: # # Hello World! # May 08 16:01:51 testvm1.both.org hello.sh: # #-Reboot-May 10 10:37:49 testvm1.both.org hello.sh: # # # May 10 10:37:49 testvm1.both.org hello.sh [842]: # Hello World! # May 10 10:37:49 testvm1.both.org hello.sh [842]: # # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # Hello World! # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # [root@testvm1 ~] #

To locate the systemd record of the hello.service unit, you can search in systemd. You can use G+Enter to turn the page to the end of the log record, and then use rollback to find the log you are interested in. Use the-b option to display only the most recently started records.

[root@testvm1] # journalctl-b-t systemdMay 10 10:37:49 testvm1.both.org systemd [1]: Starting SYSV: Late init script for live image....May 10 10:37:49 testvm1.both.org systemd [1]: Started SYSV: Late init script for live image..May 10 10:37:49 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:37:49 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10: 37:50 testvm1.both.org systemd [1]: Starting D-Bus System Message Bus...May 10 10:37:50 testvm1.both.org systemd [1]: Started D-Bus System Message Bus.

I copied some other log records to give you some idea of what you might find. This command spurts out all the log content that belongs to systemd-109183 lines when I write this. This is a large amount of data that needs to be collated. You can use the search function of the page, usually less, or you can use the built-in grep feature. The-g (or-- grep=) option can use Perl-compatible regular expressions.

[root@testvm1] # journalctl-b-t systemd-g "hello" [root@testvm1] # journalctl-b-t systemd-g "hello"-- Logs begin at Tue 2020-05-05 18:11:49 EDT, end at Sun 2020-05-10 11:01:01 EDT. -- May 10 10:37:49 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:37:49 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:37:49 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10:54:45 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:54:45 testvm1.both.org systemd [1]: hello.service: Succeeded .May 10 10:54:45 testvm1.both.org systemd [1]: Finished My hello shell script. [root@testvm1] #

You can use the standard GNU grep command, but this does not show the metadata for the first line of the log.

If you only want to see the logging that contains your hello service, you can specify a time to narrow it down. For example, I will start at 10:54:00 on my test virtual machine, which is the number of minutes for the start of the above logging. Note-the option for since= must be in quotation marks, or it can be written as-S "sometime".

Dates and times may vary on your machine, so be sure to use a timestamp that matches the time in your log.

[root@testvm1] # journalctl-- since= "2020-05-10 10:54:00" May 10 10:54:35 testvm1.both.org audit: BPF prog-id=54 op=LOADMay 10 10:54:35 testvm1.both.org audit: BPF prog-id=55 op=LOADMay 10 10:54:45 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # Hello World! # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:54:45 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10:54:45 testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd" 'May 10 10:54:45 testvm1.both.org audit [1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/"' May 10 10: 56:00 testvm1.both.org NetworkManager: [1589122560.0633] dhcp4 (enp0s3): error-113dispatching eventsMay 10 10:56:00 testvm1.both.org NetworkManager [840]: [1589122560.0634] dhcp4 (enp0s3): state changed bound-> fail

The since option skips all records at a specified point in time, but there are still a lot of records you don't need after that point in time. You can also use the until option to trim the records after the time you are interested in. I want a minute near the time of the incident, and nothing else:

[root@testvm1] # journalctl-- since= "2020-05-10 10:54:35"-- until= "2020-05-10 10:55:00"-- Logs begin at Tue 2020-05-05 18:11:49 EDT, end at Sun 2020-05-10 11:04:59 EDT. -- May 10 10:54:35 testvm1.both.org systemd [1]: Reloading.May 10 10:54:35 testvm1.both.org audit: BPF prog-id=27 op=UNLOADMay 10 10:54:35 testvm1.both.org audit: BPF prog-id=26 op=UNLOADay 10 10:54:35 testvm1.both.org audit: BPF prog-id=55 op=LOADMay 10 10:54:45 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # Hello World! # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # # May 10 10:54:45 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:54:45 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10:54:45 testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd > May 10 10:54:45 testvm1.both.org audit [1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm=" systemd "exe=" / usr/lib/systemd/ > lines 1-46 usr/lib/systemd/ 46 (END)

If there is still a lot of activity during this period of time, you can use a combination of these options to further narrow the resulting data flow:

[root@testvm1] # journalctl-- since= "2020-05-10 10:54:35"-- until= "2020-05-10 10:55:00"-t "hello.sh"-- Logs begin at Tue 2020-05-05 18:11:49 EDT, end at Sun 2020-05-10 11:10:41 EDT. -- May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # Hello World! # May 10 10:54:45 testvm1.both.org hello.sh [1380]: # # [root@testvm1 ~] #

Your result should be similar to mine. You can see from this series of experiments that the service works well.

Restart-- still get this far.

So far, you have not restarted the machine on which the service is installed. So restart now, because after all, this tutorial is about running programs in the startup phase. First, you need to enable the service in the startup sequence.

[root@testvm1 ~] # systemctl enable hello.serviceCreated symlink / etc/systemd/system/multi-user.target.wants/hello.service → / etc/systemd/system/hello.service. [root@testvm1 ~] #

Notice that the soft link is created in the / etc/systemd/system/multi-user.target.wants directory. This is because the service unit file specifies that the service is "needed" by the multi-user.target.

Restart the machine to make sure you can observe the data flow during the startup phase so that you can see the "Hello world" message. Wait a minute... Did you see that? Yeah, I see it. Although it was quickly brushed away, I did see a message from systemd that it started the hello.service service.

Look at the log since the last time the system was started. You can use the page search tool less to find "Hello" or "hello". I clipped a lot of data, but left nearby log records so that you can feel what the logging related to your service looks like locally:

[root@testvm1] # journalctl-bMay 10 10:37:49 testvm1.both.org systemd [1]: Listening on SSSD Kerberos Cache Manager responder socket.May 10 10:37:49 testvm1.both.org systemd [1]: Reached target Sockets.May 10 10:37:49 testvm1.both.org systemd [1]: Reached target Basic System.May 10 10:37:49 testvm1.both.org systemd [1]: Starting Modem Manager...May 10 10:37:49 testvm1.both.org systemd [1]: Starting Network Manager...May 10 10:37:49 testvm1.both.org systemd [1]: Starting Avahi mDNS/DNS-SD Stack...May 10 10:37:49 testvm1.both.org systemd [1]: Condition check resulted in Secure Boot DBX (blacklist) updater being skipped.May 10 10:37:49 testvm1.both.org systemd [1]: Starting My hello shell script...May 10 10:37:49 testvm1.both.org systemd [1]: Starting IPv4 firewall with iptables...May 10 10:37:49 Testvm1.both.org systemd [1]: Started irqbalance daemon.May 10 10:37:49 testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=irqbalance comm= "systemd" exe= "/ usr/lib/sy >" 'May 10 10:37:49 testvm1.both.org systemd [1]: Starting LSB: Init script for live image....May 10 10:37:49 testvm1.both.org systemd [1]: Starting Hardware Monitoring Sensors...May 10 10:37:49 testvm1.both.org Systemd [1]: Starting NTP client/server...May 10 10:37:49 testvm1.both.org systemd [1]: Starting SYSV: Late init script for live image....May 10 10:37:49 testvm1.both.org systemd [1]: Started SYSV: Late init script for live image..May 10 10:37:49 testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=livesys-late comm= "systemd" exe= "/ usr/lib/ >" 'May 10 10:37: 49 testvm1.both.org hello.sh [842]: # # May 10 10:37:49 testvm1.both.org hello.sh [842]: # Hello World! # May 10 10:37:49 testvm1.both.org hello.sh [842]: # # May 10 10:37:49 testvm1.both.org systemd [1]: hello.service: Succeeded.May 10 10:37:49 testvm1.both.org systemd [1]: Finished My hello shell script.May 10 10:37:49 testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd >" 'May 10 10:37:49 testvm1.both.org audit [1] SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/ > May 10 10:37:50 testvm1.both.org audit: BPF prog-id=28 op=LOAD

You can see that systemd starts the hello.service unit, which executes the hello.sh script and records the output in the log. If you can catch it in the startup phase, you should also see that the systemd message indicates that it is starting the script, and another message indicates that the service is successful. By looking at the first systemd message in the above data flow, you will find that systemd starts your service soon after reaching the basic system goal.

But I want to see the information printed out during the startup phase. There is one way to do this: add the following line to the [Service] paragraph of the hello.service file:

StandardOutput=journal+console

Now the hello.service file looks like this:

# Simple service unit file to use for testing# startup configurations with systemd.# By David Both# Licensed under GPL V2# [Unit] Description=My hello shell script [Service] Type=oneshotExecStart=/usr/local/bin/hello.shStandardOutput=journal+console [Install] WantedBy=multi-user.target

After adding this line, restart the system and observe the data flow scrolling on the display screen during startup. You should see the message in its small box. After the startup sequence is complete, you can view the most recent startup log and locate the log record of your new service.

Modify order

Now that your service is available, you can see where it started in the startup sequence and try to modify it. It is important to keep in mind that systemd tends to start as many services and other unit types as possible in parallel in each major goal (basic.target, multi-user.target, and graphical.**target). You should have just seen the log record of the last boot, and it should look similar to my log above.

Note that systemd starts your testing service shortly after it reaches the basic system goal (basic.target). This is exactly what you specified in the WantedBy line of the service unit file, so it is correct. Before you make any changes, list the contents in the / etc/systemd/system/multi-user.target.wants directory and you will see a soft link to the service unit file. The [Install] section of the service unit file specifies which target will start the service, and executing the systemctl enable hello.service command creates a soft link under the appropriate targets.wants path.

Hello.service-> / etc/systemd/system/hello.service

Some services need to be started during the basic.target phase, while others are not necessary unless the system is starting graphical.target. The service in this experiment will not be started during basic.target-assuming you don't need it to start until the graphical.target phase. Then modify the line WantedBy:

WantedBy=graphical.target

Be sure to disable hello.service and then re-enable it so that you can delete the old link and create a new one in the graphical.targets.wants directory. I noticed that if I forgot to disable the service before changing the target required by the service, I could run the systemctl disable command and the link would be removed from both targets.wants directories. Then I just need to restart the service and restart my computer.

There is one thing to pay attention to when starting the service under graphical.target. If the computer starts up to the multi-user.target phase, the service will not start automatically. If the service requires a GUI desktop interface, this may be what you want, but it may not be what you want either.

Use the-o short-monotonic option to view the logs of graphical.target and multi-user.target, showing the logs a few seconds after the kernel starts, with a precision of microseconds:

[root@testvm1] # journalctl-b-o short-monotonic

Some of the logs of multi-user.target:

[17.264730] testvm1.both.org systemd [1]: Starting My hello shell script... [17.265561] testvm1.both.org systemd [1]: Starting IPv4 firewall with iptables... [19.478468] testvm1.both.org systemd [1]: Starting LSB: Init script for live image.... [19.507359] testvm1.both.org iptables.init [844]: iptables: Applying firewall rules: [OK] [19.507835] testvm1.both.org hello.sh [843]: # # [19.507835] testvm1.both.org hello.sh [843]: # Hello World! # [19.507835] testvm1.both.org hello.sh [843]: # # [21.482481] testvm1.both.org systemd [1]: hello.service: Succeeded. [21.482550] testvm1.both.org smartd [856]: Opened configuration file / etc/smartmontools/smartd.conf [21.482605] testvm1.both.org systemd [1]: Finished My hello shell script.

There are also some graphical.target logs:

[19.436815] testvm1.both.org systemd [1]: Starting My hello shell script... [19.437070] testvm1.both.org systemd [1]: Starting IPv4 firewall with iptables... [19.612614] testvm1.both.org hello.sh [841]: # # [19.612614] testvm1.both.org hello.sh [841]: # # Hello World! # [19.612614] testvm1.both.org hello.sh: # # [19.629455] testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/systemd" hostname=? Addr=? Terminal=? Res=success' [19.629569] testvm1.both.org audit [1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/systemd" hostname=? Addr=? Terminal=? Res=success' [19.629682] testvm1.both.org systemd [1]: hello.service: Succeeded. [19.629782] testvm1.both.org systemd [1]: Finished My hello shell script.

Although the WantedBy section of the unit file contains the graphical.target,hello.service unit running about 19.5 or 19.6 seconds after startup. But hello.service starts at 17.24 seconds in multi-user.target and 19.43 seconds in graphical target.

What does that mean? Check out the link / etc/systemd/system/default.target. The contents of the file show that systemd starts the default target graphical.target first, and then graphical.target triggers multi-user.target.

[root@testvm1 system] # cat default.target# SPDX-License-Identifier: LGPL-2.1+## This file is part of systemd.## systemd is free software; you can redistribute it and/or modify it# under the terms of the GNU Lesser General Public License as published by# the Free Software Foundation; either version 2.1of the License, or# (at your option) any later version. [Unit] Description=Graphical InterfaceDocumentation=man:systemd.special (7) Requires=multi-user.targetWants=display-manager.serviceConflicts=rescue.service rescue.targetAfter=multi-user.target rescue.service rescue.target display-manager.serviceAllowIsolate=yes [root@testvm1 system] #

Whether you start the service with graphical.target or multi-user.target, the hello.service unit starts 19.5 or 19.6 seconds after startup. Based on this fact and the log results (especially those with monotonous output), you know that these goals are started in parallel. Take a look at another thing in the log:

[28.397330] testvm1.both.org systemd [1]: Reached target Multi-User System. [28.397431] testvm1.both.org systemd [1]: Reached target Graphical Interface.

Both goals were accomplished almost at the same time. This is consistent with the theory, because graphical.target triggers multi-user.target, and it will not be completed until the multi-user.target arrives (that is, complete). But hello.service finished much earlier than this.

All this shows that the two goals are started almost in parallel. If you check the log, you will find that the various goals and services from such major goals are mostly started in parallel. Obviously, multi-user.target doesn't have to be done before graphical.target starts. Therefore, simply using these main goals does not sort the startup sequence very well, although it is useful in ensuring that units start only when they are needed by graphical.target.

Roll back the hello.service unit file to WantedBy=multi-user.target (if you haven't already done so) before continuing.

Ensure that a service starts after the network is running

A common startup problem is to ensure that a unit starts after the network is up and running. As mentioned in Freedesktop.org 's article "running the service after the network starts", there is no real consensus on when the network is counted as "started". However, this article provides three options, and it is network-online.target that meets the needs of a fully available network. It is important to note that network.target is used during the shutdown phase rather than the startup phase, so it is not helpful for you to do an orderly startup.

Before making any changes, be sure to check the log to make sure that the hello.service unit starts correctly before the network is available. You can check network-online.target in the log to confirm.

Your service doesn't really need a network service, but you can think of it as a network service.

Because setting up WantedBy=graphical.target does not guarantee that the service will start after the network is available, you need other ways to do this. Fortunately, there is an easy way to do this. Add the following two lines of code to the [Unit] section of the hello.service unit file:

After=network-online.target Wants=network-online.target

Both fields are required to take effect. Restart the machine and find the service record in the log:

[26.083121] testvm1.both.org NetworkManager: [1589227764.0293] device (enp0s3): Activation: successful Device activated. [26.083349] testvm1.both.org NetworkManager [842]: [1589227764.0301] manager: NetworkManager state is now CONNECTED_GLOBAL [26.085818] testvm1.both.org NetworkManager [842]: [1589227764.0331] manager: startup complete [26.089911] testvm1.both.org systemd [1]: Finished NetworkManager Wait Online. [26.090254] testvm1.both.org systemd [1]: Reached target Network is Online. [26.090399] testvm1.both.org audit [1 ]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=NetworkManager-wait-online comm= "systemd" exe= "/ usr/lib/systemd/systemd" hostname=? Addr=? Termina > "'[26.091991] testvm1.both.org systemd [1]: Starting My hello shell script... [26.095864] testvm1.both.org sssd [beats _ files] [1007]: Starting up [26.290539] testvm1.both.org systemd [1]: Condition check resulted in Login and scanning of iSCSI devices being skipped. [26.291075] testvm1.both.org systemd [1]: Reached target Remote File Systems (Pre). [26.291154] testvm1.both.org systemd [ 1]: Reached target Remote File Systems. [26.292671] testvm1.both.org systemd [1]: Starting Notify NFS peers of a restart... [26.294897] testvm1.both.org systemd [1]: iscsi.service: Unit cannot be reloaded because it is inactive. [26.304682] testvm1.both.org hello.sh [1010]: # # [26.304682] Testvm1.both.org hello.sh [1010]: # Hello World! # [26.304682] testvm1.both.org hello.sh [1010]: # # [26.306569] testvm1.both.org audit [1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/systemd" hostname=? Addr=? Terminal=? Res=success' [26.306669] testvm1.both.org audit [1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=hello comm= "systemd" exe= "/ usr/lib/systemd/systemd" hostname=? Addr=? Terminal=? Res=success' [26.306772] testvm1.both.org systemd [1]: hello.service: Succeeded. [26.306862] testvm1.both.org systemd [1]: Finished My hello shell script. [26.584966] testvm1.both.org sm-notify [1011]: Version 2.4.3 starting

This confirms that the hello.service unit will start after network-online.target. This is exactly what you want. You may also have seen the "Hello World" message appear during the startup phase. It is also important to note that the timestamp recorded at startup is about 6 seconds later than before.

The best way to define a startup sequence

This article explores in detail the details of systemd and unit files and logs when Linux starts, and finds out what happens when errors are introduced into unit files. As a system administrator, I find that such experiments help me understand the behavior of programs or services when they fail, and intentional sabotage in a secure environment is a good way to learn.

The experimental results in this paper show that adding a service unit to multi-user.target or graphical.target alone does not determine its position in the startup sequence. It only determines whether a unit is started as part of the graphical environment. In fact, the startup targets multi-user.target and graphical.target and all of their Wants and Required are started almost in parallel. The best way to ensure that a unit starts at a specific location is to determine which unit it depends on and configure the new unit to be Want and After its dependencies.

Thank you for your reading, the above is the content of "how to use systemd to manage startup items". After the study of this article, I believe you have a deeper understanding of how to use systemd to manage startup items, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 295

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report