1. 探索Systemd

1.1. 系统管理

systemd不是一个命令,而是一组命令的集合,提供了一个系统和服务管理器,运行为 PID 1 并负责启动其它程序。 下图为systemd的架构图。

../../_images/systemd_pre00.PNG

systemd功能包括:支持并行化任务;同时采用 socket 式与 D-Bus 总线式激活服务; 按需启动守护进程(daemon);利用 Linux 的 cgroups 监视进程;支持快照和系统恢复; 维护挂载点和自动挂载点;各服务间基于依赖关系进行精密控制。 systemd 支持 SysV 和 LSB 初始脚本,可以替代 sysvinit。除此之外, 功能还包括日志进程、控制基础系统配置,维护登陆用户列表以及系统账户、运行时目录和设置, 可以运行容器和虚拟机,可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。

1.2. Systemd–核心概念

1.2.1. unit

单元,单元文件是 ini 风格的纯文本文件,Systemd 可以管理所有系统资源,不同的资源统称为 Unit(单位)。 其封装了12种对象的信息:服务(service)、套接字(socket)、设备(device)、挂载点(mount)、 自动挂载点(automount)、 启动目标(target)、交换分区或交换文件(swap)、被监视的路径(path)、 任务计划(timer)、 资源控制组(slice)、一组外部创建的进程(scope)、快照(snapshot)。

  • service:一个后台服务进程,其封装了守护进程的启动、停止、重启与重载等操作。

  • socket:此类配置单元封装系统和互联网中的一个套接字。当下,systemd支持流式, 数据报和连续包的 AF_INET,AF_INET6,AF_UNIX socket。 每个套接字配置单元都有一个相应的服务配置单元, 相应的服务在第一个“连接”进入套接字时就会启动(例如:nscd.socket在有新连接后便启动nscd.service), 监控系统或者网络的数据信息。

  • device:此类配置单元封装一个存在于Linux设备树中的设备。 每个使用udev规则标记的设备都将会在systemd中作为一个设备配置单元出现, 定义设备之间的依赖关系。

  • mount:此类配置单元封装文件系统结构层次中的一个挂载点。 systemd将对这个挂载点进行监控和管理。比如,可以在启动时自动将其挂载, 可以在某些条件下自动卸载。systemd会将/etc/fstab中的条目都转换为挂载点,并在开机时处理。

  • automount:此类配置单元封装系统结构层次中的一个自挂载点。 每个自挂载配置单元对应一个挂载配置单元,当该自动挂载点被访问时, systemd执行挂载点中定义的挂载行为。

  • Swap:和挂载配置单元类似,交换配置单元用来管理交换分区。 用户可以用交换配置单元来定义系统中的交换分区,可以让这些交换分区在启动时被激活。

  • target:此类配置单元为其他配置单元进行逻辑分组。它们本身实际上并不做什么, 只是引用其他配置单元而已,这样便可以对配置单元做一个统一的控制, 就可以实现大家都非常熟悉的运行级别的概念。比如,想让系统进入图形化模式, 需要运行许多服务和配置命令,这些操作都由一个个的配置单元表示, 将所有的这些配置单元组合为一个目标(target),就表示需要将这些配置单元全部执行一遍, 以便进入目标所代表的系统运行状态(例如:multi-user.target相当于在传统使用sysv的系统中运行级别5)。

  • timer:定时器配置单元用来定时触发用户定义的操作。这类配置单元取代了atd,crond等传统的定时服务。

  • snapshot:与target配置单元相似,快照是一组配置单元,它保存了系统当前的运行状态。

  • slice:表示一个CGroup 的树。

  • path:监控指定目录或文件的变化,并触发其它 Unit 的运行。

  • scope:它用于描述一些系统服务的分组信息。

每个配置单元都有一个对应的配置文件, 比如一个avahi-daemon服务对应一个avahi-daemon.service文件。 这种配置文件的语法非常简单,用户不需要再编写和维护复杂的sysv脚本了。

# 列出正在运行的 Unit
$ systemctl list-units
../../_images/systemd_pre01.PNG
# 列出所有Unit,包括没有找到配置文件的或者启动失败的
$ systemctl list-units --all

# 列出所有没有运行的 Unit
$ systemctl list-units --all --state=inactive
../../_images/systemd_pre02.PNG
# 列出所有加载失败的 Unit
$ systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
$ systemctl list-units --type=service
../../_images/systemd_pre03.PNG
# 显示某个 Unit 是否正在运行
$ systemctl is-active systemd-timesyncd.service
../../_images/systemd_pre04.PNG
# 显示某个 Unit 服务是否建立了启动链接
$ systemctl is-enabled systemd-timesyncd.service
../../_images/systemd_pre05.PNG

1.2.2. unit–管理

# 立即启动一个服务
$ sudo systemctl start sshd.service

# 立即停止一个服务
$ sudo systemctl stop sshd.service

# 重启一个服务
$ sudo systemctl restart sshd.service

# 杀死一个服务的所有子进程
$ sudo systemctl kill sshd.service

# 重新加载一个服务的配置文件
$ sudo systemctl reload sshd.service

# 重载所有修改过的配置文件
$ sudo systemctl daemon-reload

# 显示某个 Unit 的所有底层参数
$ systemctl show httpd.service
../../_images/systemd_pre06.PNG
# 显示某个 Unit 的指定属性的值
$ systemctl show -p CPUShares avahi-daemon.service

1.2.3. unit–依赖

尽管systemd将大量的启动工作解除了依赖,使得它们可以并行启动。但还是存在一些任务, 它们之间存在天生的依赖关系,不能用“套接字激活”(socket activation), D-Bus activation和autofs三大方法来解除依赖。比如,挂载必须等待挂载点在文件系统中被创建; 挂载也必须等待相应的物理设备就绪。为了解决这类依赖问题,systemd的配置单元之间可以彼此定义依赖关系。 比如,unit Q依赖unit W,可以在unit W的定义中用“require Q”来表示,这样systemd就会保证先启动Q再启动W。 systemd能保证事务完整性。systemd的事务概念和数据库中的有所不同, 主要是为了保证多个依赖的配置单元之间没有环形引用。若存在循环依赖,那么systemd将无法启动任意一个服务。 此时,systemd将会尝试解决这个问题,因为配置单元之间的依赖关系有两种:requireds为强依赖,wants为弱依赖, systemd将去掉wants关键字指定的依赖看看是否能打破循环。如果无法修复,systemd会报错。 systemd能够自动检测和修复这类配置错误,极大地减轻了管理员的拔锚负担。

# 命令列出一个 Unit 的所有依赖
$ systemctl list-dependencies sshd.service
../../_images/systemd_pre07.PNG

上面命令的输出结果之中,有些依赖是 Target 类型,而 Target 类型默认是不会展开显示的。 若要展开显示 Target,则需要添加–all参数。

# 命令列出一个 Unit 的所有依赖,并展开显示Target 依赖类型
$ systemctl list-dependencies --all sshd.service

1.2.4. unit–配置文件

systemd的配置文件默认会存放于文件系统中的/etc/systemd/system或/usr/lib/systemd/system目录下, 我们输入“ls -al”命令查看一下该目录的内容。

../../_images/systemd_pre08.PNG

可以看到该目录下有很多链接符号“->”,这代表着文件的实体是“->”指向的文件,可以说是软链接的关系, 和windows上的快捷方式类似(有点类似月老牵线^-^), 而这些软链接所指向的目录绝大多数是/lib/systemd/system目录, 也有指向/dev/null文件的,这代表它是一个空文件, 初始化过程中systemd只执行/etc/systemd/system目录里面的配置文件。 当你安装完systemd程序之后,他会自动的在/lib/systemd/system目录下生成一个与该程序对应的配置文件。 你可以使用“systemctl enable xxx.service”的方式来建立一个服务软链接, 若设置了开机启动,则“systemctl enable”相当于使能开机启动, 而“systemctl disable”命令与之相反,他会断开软链接,所以开机就不会启动。

# 检查某个单元是否是开机自启动的(建立的启动链接)
$ systemctl is-enabled sshd.service
../../_images/systemd_pre09.PNG

1.2.5. unit–系统管理

# 重启系统(异步操作)
$ systemctl reboot
../../_images/systemd_pre10.PNG
# 关闭系统,切断电源(异步操作)
$ systemctl poweroff

# 仅CPU停止工作,其他硬件仍处于开机状态(异步操作)
$ systemctl halt

# 暂停系统(异步操作),执行suspend.target
$ systemctl suspend

# 使系统进入冬眠状态(异步操作),执行hibernate.target
$ systemctl hibernate

1.2.6. unit–日志管理

Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令, 查看所有日志(内核日志和应用日志)。

日志配置文件位于/etc/systemd/journald.conf,其保存目录为/var/log/journal/ 默认情况下日志最大限制为所在文件系统容量的 10%, 可通过/etc/systemd/journald.conf 中的 SystemMaxUse 字段来指定日志最大限制。

注意

/var/log/journal/目录是 systemd 软件包的一部分。 若被删除,systemd 不会自动创建它,直到下次升级软件包时重建该目录。 如果该目录缺失,systemd 会将日志记录写入 /run/systemd/journal。 这意味着,系统重启后日志将丢失。

# 查看所有日志
$ sudo journalctl
../../_images/systemd_pre11.PNG
# 指定日志文件占据的最大空间
$ sudo journalctl --vacuum-size=8M

1.3. Systemd–实例分析

1.3.1. 启动顺序及依赖

前面我们讲到了服务的配置文件,系统上电后,systemd便会读取每个服务地配置文件, 然后根据配置文件执行每个系统服务,配置文件详细地描述了一个服务是如何启动的. 我们以ssh服务为例,详细分析其配置文件。 在/etc/systemd/system目录下找到sshd.service文件, 它描述了如何启动一个ssh服务,使用vim.tiny打开该配置文件,如下图所示:

../../_images/systemd_pre12.PNG

可以看到,配置文件一共有三个区块,分别是Unit、Service、Install,每个区块又包含了许多键值对。

其中Unit区块中,Description描述了当前服务,Documentation字段给出了文档位置, 紧接着的是比较重要的After字段,它指定了服务的启动顺序,但是不涉及依赖关系, 与之对应的是Before字段。以本配置文件为例, After表示的是当前服务需要在network.target及auditd.service两个服务之后启动。 而Wants和Requires字段只涉及依赖关系,他与启动顺序是无关的,默认为同时启动。 如果想要设置服务之间的依赖关系,及使用Wants和Requires字段即可, Wants为“弱依赖”,Requires为“强依赖”。

1.3.2. 启动命令

EnvironmentFile字段指定了当前服务的环境参数文件,注意等号后面的“-”, 它表示如果/etc/default/ssh文件不存在也不会抛出错误,ExecStart是配置文件最重要的字段, 它定义了启动一个进程需要执行的命令。 图中执行的命令是“/usr/sbin/sshd -D $SSHD_OPTS”, 其中的变量$SSHD_OPTS就是来自于EnvironmentFile字段所指定的环境参数文件。 ExecStartPre字段表示启动服务之前需要执行的命令。

1.3.3. 启动类型与行为

  1. Type字段指定了服务的启动类型,它的类型如下所示。

    • simple(默认值):ExecStart字段启动的进程为主进程

    • forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程

    • oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务

    • dbus:类似于simple,但会等待 D-Bus 信号后启动

    • notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务

    • idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。 一种使用场合是为让该服务的输出,不与其他服务的输出相混合

  2. KillMode字段定义了systemd如何停止ssh服务,本例设置为process, 表示只停止主进程,但不停止sshd的子进程。

  3. Restart字段定义了sshd退出后,systemd的重启方式,Restart设为on-failure, 表示任何意外的失败,就将重启sshd。如果sshd正常停止(如执行systemctl stop命令), 它就不会重启。其可设置成下面值。

    • no(默认值):退出后不会重启

    • on-success:只有正常退出时(退出状态码为0),才会重启

    • on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启

    • on-abnormal:只有被信号终止和超时,才会重启

    • on-abort:只有在收到没有捕捉到的信号终止时,才会重启

    • on-watchdog:超时退出,才会重启

    • always:不管是什么退出原因,总是重启

1.3.4. 安装方式

WantedBy字段表示当前服务所在的Target,Target表示的是服务组, sshd所在的服务组为multi-user.target。 当执行“systemctl enable sshd.service”命令的时候, sshd.service的一个符号链接, 就会放在/etc/systemd/system目录下面的multi-user.target.wants子目录之中。

如果我们修改了配置文件,就需要重新加载配置文件,然后重启该服务。

# 重新加载配置文件
$ sudo systemctl daemon-reload

# 重启相关服务
$ sudo systemctl restart ssh

1.4. Systemd–创建自己的Systemd服务

我们经常有这样的需求,自己写好一个应用,想要它实现开机自启动的功能, 那么我们可以通过创建一个Systemd服务服务来实现。 下面我以创建一个简单的hello.service服务为例子,教大家如何创建自己的Systemd服务。

1.4.1. 编写脚本

cd进入/opt目录下,使用vim编写一个hello.sh脚本。

1
2
3
4
5
6
7
#!/bin/bash

while true
do
    echo Hello Lubancat >> /tmp/hello.log
    sleep 3
done

该脚本实现的功能是每隔3秒就打印“Hello Lubancat”字符串到/tmp/hello.log文件中。 编写好后记得赋予hello.sh可执行权限。

sudo chmod 0755 hello.sh

1.4.2. 创建配置文件

在/etc/systemd/system/目录下创建一个hello.service配置文件,内容如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Unit]
Description = hello daemon

[Service]
ExecStart = /opt/hello.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

其中ExecStart字段定义了hello.service服务的自启动脚本为/opt/hello.sh, 当我们使能了hello.service开机自启功能,在开机后便会执行/opt/hello.sh。 Restart = always表示指进程或服务意外故障的时候可以自动重启的模式。 Type = simple为默认的,可以不填。WantedBy指定服务由谁启动,WantedBy = multi-user.target 表示 在系统启动到多用户模式时就会把这个服务添加到启动顺序中。如果需要在图形用户界面后再启动,需要设置为 WantedBy = graphical.target,表示需要在系统进入图形用户界面模式时启动。

也就是说,WantedBy参数对于服务是否需要桌面环境十分重要,如果服务需要桌面环境,然而设置WantedBy = multi-user.target 在桌面启动前就调用自己的启动脚本,将会导致服务启动失败!

1
2
3
4
5
6
#在桌面前就启动服务
WantedBy = multi-user.target


#进入桌面后启动服务
WantedBy = graphical.target

1.4.3. 使能hello.service开机自启功能

输入命令“sudo systemctl list-unit-files –type=service | grep hello” 查看hello.service是否被添加到了服务列表。

sudo systemctl list-unit-files --type=service | grep hello
../../_images/systemd_pre131.PNG

可以看到hello.service处于disable状态,如果你输入上面命令后没有任何显示, 那你创建的服务就处理问题,需要仔细排查。我们输入下面命令使hello.service开机自启动。

sudo systemctl enable hello
sudo systemctl start hello

然后使用reboot命令重启系统, 启动系统后输入“sudo systemctl status hello”命令即可看到hello.service处于运行状态。

sudo systemctl status hello

cat /tmp/hello.log
../../_images/systemd_pre141.PNG

关于systemd的知识点还有很多,这里做简单介绍,主要是让大家了解systemd的基本用法及启动服务的流程, 感兴趣的可以在网上查阅相关文档。

如果使用桌面环境的用户建议使用桌面系统自带的自启动方式,详情请参考:

1.5. Systemd–基本工具

1.5.1. systemctl

监视和控制systemd的主要命令是systemctl。该命令可用于查看系统状态和管理系统及服务。

#输出激活的单元
systemctl

#打印信息如下

UNIT                      LOAD   ACTIVE     SUB       JOB   DESCRIPTION
sys-devices-platform-3c0800000.pcie-pci0002:20-0002:20:00.0-0002:21:00.0-nvme-nv
sys-devices-platform-backlight-backlight-backlight.device loaded active     plug
sys-devices-platform-fe010000.ethernet-net-eth1.device loaded active     plugged
sys-devices-platform-fe2a0000.ethernet-net-eth0.device loaded active     plugged
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0-mmcblk
sys-devices-platform-fe310000.sdhci-mmc_host-mmc0-mmc0:0001-block-mmcblk0.device
sys-devices-platform-fiq_debugger.0-tty-ttyFIQ0.device loaded active     plugged
sys-devices-platform-rk809\x2dsound-sound-card0.device loaded active     plugged
sys-devices-virtual-block-ram0.device loaded active     plugged         /sys/dev
sys-devices-virtual-block-zram0.device loaded active     plugged         /sys/de
sys-devices-virtual-misc-rfkill.device loaded active     plugged         /sys/de
sys-devices-virtual-tty-ttyGS0.device loaded active     plugged         /sys/dev
sys-module-configfs.device loaded active     plugged         /sys/module/configf
#显示系统状态
systemctl status -l

#打印信息如下
● lubancat
    State: starting
    Jobs: 11 queued
Failed: 0 units
    Since: Tue 2022-10-11 13:59:30 CST; 5min ago
CGroup: /
        ├─user.slice
        │ ├─user-0.slice
        │ │ ├─session-c2.scope
        │ │ │ ├─ 557 /bin/login -p --
        │ │ │ ├─1021 -bash
        │ │ │ ├─1160 systemctl status -l
        │ │ │ └─1161 pager
        │ │ └─user@0.service
        │ │   └─init.scope
        │ │     ├─1006 /lib/systemd/systemd --user
        │ │     └─1009 (sd-pam)
        │ └─user-1000.slice
        │   ├─user@1000.service
        │   │ ├─pulseaudio.service
        │   │ │ └─686 /usr/bin/pulseaudio --daemonize=no --log-target=journal
        │   │ └─init.scope
        │   │   ├─674 /lib/systemd/systemd --user
lines 1-23
# 重启系统
$ sudo systemctl reboot

# 暂停系统
$ sudo systemctl suspend

# 关闭系统,切断电源
$ sudo systemctl poweroff

# CPU停止工作
$ sudo systemctl halt

# 让系统进入冬眠状态
$ sudo systemctl hibernate

# 让系统进入交互式休眠状态
$ sudo systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
$ sudo systemctl rescue

# 输出运行失败的单元
$ systemctl --failed

1.5.2. systemd-analyze

systemd-analyze命令用于查看启动耗时。

#查看启动耗时
systemd-analyze

#打印信息
Startup finished in 1.809s (kernel) + 49.887s (userspace) = 51.696s
graphical.target reached after 49.834s in userspace
#查看每个服务的启动耗时
systemd-analyze blame

#打印信息
44.661s snapd.seeded.service
 3.820s man-db.service
 3.586s blueman-mechanism.service
 3.500s fstrim.service
 2.270s networkd-dispatcher.service
 2.214s dev-mmcblk0p3.device
 2.051s adbd.service
 1.884s snapd.service
 1.504s async.service
 1.355s logrotate.service
 1.025s accounts-daemon.service
  960ms NetworkManager.service
  823ms polkit.service
  687ms systemd-resolved.service
  627ms avahi-daemon.service
  613ms ModemManager.service
  550ms systemd-journald.service
  530ms systemd-logind.service
  505ms switcheroo-control.service
  481ms apport.service
  451ms wpa_supplicant.service
  441ms e2scrub_reap.service
  427ms colord.service
  425ms systemd-udev-trigger.service
  408ms networking.service
  391ms kerneloops.service
  355ms fwupd-refresh.service
  345ms ssh.service
  303ms packagekit.service
  284ms alsa-restore.service
  265ms user@0.service
  249ms user@112.service
  225ms systemd-udevd.service
  205ms ntp.service
  184ms rsyslog.service
  168ms lightdm.service
  156ms pppd-dns.service
  148ms rkwifibt.service
  136ms systemd-user-sessions.service
  127ms e2scrub_all.service
  124ms systemd-fsck@dev-disk-by\x2dpartlabel-boot.service
  106ms systemd-journal-flush.service
  102ms dev-mqueue.mount
  101ms bluetooth.service
   97ms sys-kernel-debug.mount
   93ms vsftpd.service
   90ms motd-news.service
   90ms sys-kernel-tracing.mount
   89ms systemd-sysctl.service
   88ms systemd-sysusers.service
   86ms systemd-backlight@backlight:backlight.service
   82ms systemd-random-seed.service
   73ms modprobe@pstore_blk.service
   72ms modprobe@pstore_zone.service
   71ms modprobe@efi_pstore.service
   67ms systemd-pstore.service
   62ms modprobe@chromeos_pstore.service
   60ms systemd-modules-load.service
   58ms systemd-remount-fs.service
   49ms systemd-tmpfiles-setup.service
   47ms plymouth-quit-wait.service
   44ms systemd-update-utmp-runlevel.service
   41ms user-runtime-dir@112.service
   38ms systemd-tmpfiles-setup-dev.service
   35ms user-runtime-dir@0.service
   35ms systemd-update-utmp.service
   27ms sys-fs-fuse-connections.mount
   24ms sys-kernel-config.mount
   21ms boot.mount
   21ms plymouth-read-write.service
   18ms ifupdown-pre.service
   18ms rtkit-daemon.service
   13ms tmp.mount
    3ms snapd.socket
#显示瀑布状的启动过程流
systemd-analyze critical-chain

#打印信息
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

graphical.target @49.834s
└─multi-user.target @49.834s
  └─snapd.seeded.service @5.169s +44.661s
    └─snapd.service @3.271s +1.884s
      └─basic.target @3.094s
        └─sockets.target @3.094s
          └─snapd.socket @3.089s +3ms
            └─sysinit.target @3.069s
              └─systemd-update-utmp.service @3.033s +35ms
                └─systemd-tmpfiles-setup.service @2.973s +49ms
                  └─local-fs.target @2.960s
                    └─boot.mount @2.938s +21ms
                      └─systemd-fsck@dev-disk-by\x2dpartlabel-boot.service @2.809s +124ms
                        └─dev-disk-by\x2dpartlabel-boot.device @2.778s
# 显示指定服务的启动流
$ systemd-analyze critical-chain sshd.service

1.5.3. hostnamectl

hostnamectl命令可用于查看当前的主机信息,当然也可以直接输入hostname来查看,但是当我们 想要修改主机名的时候就显得没那么方便,每次都要找到hostname文件,并将其打开再做修改,hostnamectl 使得我们对主机名的操作更加简便。

#显示当前主机的信息
hostnamectl

#打印信息
    Static hostname: lubancat
          Icon name: computer
         Machine ID: 994b8b2798844992a0691925b398fab5
            Boot ID: 21de30a7c6ee4a75b619fe31bd53a415
   Operating System: Debian GNU/Linux 10 (buster)
             Kernel: Linux 4.19.232
       Architecture: arm64


#修改主机名
root@npi:~# sudo hostnamectl set-hostname cat

#再次查看主机信息
root@npi:~# hostnamectl
    Static hostname: cat
          Icon name: computer
         Machine ID: 994b8b2798844992a0691925b398fab5
            Boot ID: 21de30a7c6ee4a75b619fe31bd53a415
   Operating System: Debian GNU/Linux 10 (buster)
             Kernel: Linux 4.19.232
       Architecture: arm64

可以看到主机名Static hostname已被修改。

1.5.4. localectl

localectl命令可用于查询与修改系统的本地化(locale)与键盘布局的设置。 它通过与 systemd-localed.service(8) 通信来修改例如 /etc/locale.conf 与 /etc/vconsole.conf 之类的配置文件。本地化设置控制着用户界面的语言、字符类型与字符编码、 日期时间与货币符号的表达方式等许多细节。

#查看本地化设置
localectl

#打印消息
    System Locale: LANG=C.UTF-8
        VC Keymap: n/a
       X11 Layout: us
        X11 Model: pc105


#设置系统本地语言和键盘
root@zhan:~# sudo localectl set-locale LANG=en_GB.utf8
root@zhan:~# sudo localectl set-keymap en_GB

#再次查看
root@lubancat:~# localectl
    System Locale: LANG=en_GB.utf8
        VC Keymap: en_GB
       X11 Layout: us
        X11 Model: pc105

1.5.5. timedatectl

timedatectl命令可以查询和更改系统时钟和设置, 你可以使用此命令来设置或更改当前的日期,时间和时区,或实现与远程NTP服务器的自动系统时钟同步。

#查看当前时区设置
timedatectl

#显示所有可用的时区
timedatectl list-timezones

#选择中国上海的时区
timedatectl set-timezone "Asia/Shanghai"

#关闭网络时间同步
timedatectl set-ntp no

#开启网络时间同步
timedatectl set-ntp yes

#设置时间和日期
timedatectl set-time 9:40:20
timedatectl set-time 2021-4-16

在设置时间与日期时要关闭时间同步功能。

1.5.6. loginctl

loginctl命令可用于检查和控制systemd的状态;查看已经登录的用户会话消息。

#显示所有会话及属性
loginctl -a

#显示会话配置消息
loginctl show-session

#列出显示指定用户的信息
loginctl show-user root