systemctl命令介绍和使用

13次阅读

共计 5803 个字符,预计需要花费 15 分钟才能阅读完成。

Systemd 程序

Systemd 其实是 Linux 系统用来管理系统的一个程序,用来代替原来的 init 进程(用来管理启动系统其它的服务进程),现在很多 Linux 发行版都已经自带 Systemd 程序了。


systemctl 命令

1. Unit

systemctl 命令是 Systemd 中最重要的一个命令,用于对服务进行启动,停止等操作,在 Systemd 中有 Unit 的概念,每个进程都是一个 Unit,总共有十二种 Unit 类型。

  • Service unit,系统服务
  • Target unit,多个 Unit 构成的一个组
  • Device Unit,硬件设备
  • Mount Unit,文件系统的挂载点
  • Automount Unit,自动挂载点
  • Path Unit,文件或路径
  • Scope Unit,不是由 Systemd 启动的外部进程
  • Slice Unit,进程组
  • Snapshot Unit,Systemd 快照,可以切回某个快照
  • Socket Unit,进程间通信的 socket
  • Swap Unit,swap 文件
  • Timer Unit,定时器

2. 常用命令

# 列出正在运行的 Unit
systemctl list-units,可以直接使用 systemctl

# 列出所有 Unit,包括没有找到配置文件的或者启动失败的
systemctl list-units --all

# 列出所有没有运行的 Unit
systemctl list-units --all --state=inactive

# 列出所有加载失败的 Unit
systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
systemctl list-units --type=service

# 显示某个 Unit 是否正在运行
systemctl is-active application.service

# 显示某个 Unit 是否处于启动失败状态
systemctl is-failed application.service

# 显示某个 Unit 服务是否建立了启动链接
systemctl is-enabled application.service

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

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

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

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

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

systemctl 中 Unit 的配置文件

上面说了每个服务都是一个 Unit,那每个 Unit 都会有它的配置文件,这样启动的时候才知道要按照什么方式去启动。Systemd 默认从目录 /etc/systemd/system/ 读取配置文件。但是里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。

1. 查看 Unit 的配置文件

可以使用 ```systemctl cat``` 命令来查看服务的配置文件,下面是 Mysql 的配置文件,很多软件已经支持 Systemd 程序了,安装的时候会自动配置它的 Unit 配置文件,例如 Mysql 和 Nginx 等等。```
[root@VM_0_11_centos ~]# systemctl cat mysqld
# /usr/lib/systemd/system/mysqld.service

[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/var/run/mysqld/mysqld.pid
# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0
# Execute pre and post scripts as root
PermissionsStartOnly=true
# Needed to create system tables
ExecStartPre=/usr/bin/mysqld_pre_systemd
# Start main service
ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS
# Use this to switch malloc implementation
EnvironmentFile=-/etc/sysconfig/mysql
# Sets open_files_limit
LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false

```

2. Unit 配置文件的含义


可以看到 Unit 配置文件有很多标签,不同的标签都代表了不同的意思,这里只列出部分介绍,可以去官网查看 Unit 配置文件文档介绍,https://www.freedesktop.org/software/systemd/man/systemd.unit.html。- Unit
   - Description,服务的描述
   - Documentation,文档介绍
   - After,该服务要在什么服务启动之后启动,比如 Mysql 需要在 network 和 syslog 启动之后再启动
- Install
   - WantedBy,值是一个或多个 Target,当前 Unit 激活时 (enable) 符号链接会放入 /etc/systemd/system 目录下面以 Target 名 +.wants 后缀构成的子目录中
   - RequiredBy,它的值是一个或多个 Target,当前 Unit 激活 (enable) 时,符号链接会放入 /etc/systemd/system 目录下面以 Target 名 +.required 后缀构成的子目录中
   - Alias,当前 Unit 可用于启动的别名
   - Also,当前 Unit 激活 (enable) 时,会被同时激活的其他 Unit
- Service
   - Type,定义启动时的进程行为。它有以下几种值。- Type=simple,默认值,执行 ExecStart 指定的命令,启动主进程
   - Type=forking,以 fork 方式从父进程创建子进程,创建后父进程会立即退出
   - Type=oneshot,一次性进程,Systemd 会等当前服务退出,再继续往下执行
   - Type=dbus,当前服务通过 D -Bus 启动
   - Type=notify,当前服务启动完毕,会通知 Systemd,再继续往下执行
   - Type=idle,若有其他任务执行完毕,当前服务才会运行
   - ExecStart,启动当前服务的命令
   - ExecStartPre,启动当前服务之前执行的命令
   - ExecStartPost,启动当前服务之后执行的命令
   - ExecReload,重启当前服务时执行的命令
   - ExecStop,停止当前服务时执行的命令
   - ExecStopPost,停止当其服务之后执行的命令
   - RestartSec,自动重启当前服务间隔的秒数
   - Restart,定义何种情况 Systemd 会自动重启当前服务,可能的值包括 always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
   - TimeoutSec,定义 Systemd 停止当前服务之前等待的秒数
   - Environment,指定环境变量

自定义服务启动

既然 Systemd 的作用就是控制服务的启动,那么就可以把自己的服务添加进去,就可以直接使用 systemctl 命令来控制服务的启动,或者是设置开机自动启动等等。

1. 创建 Unit 配置文件

在 ```/usr/lib/systemd/system``` 目录中创建自己的配置文件,一般都是 ```.service``` 结尾,例如这里创建了一个 ```test-sh.service``` 配置文件,这个 Unit 是为了启动我们自己的一个 shell 脚本。```
# /usr/lib/systemd/system/test-sh.service
[Unit]
Description= test sh log

[Service]
ExecStart=/opt/dev/shell/test.sh
Type=forking
KillMode=process
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

```

2. 创建脚本


在上面配置文件指定的启动路径 ```/opt/dev/shell/``` 下创建 shell 脚本,这里只是每秒打印当前时间,并输出到一个文本中。```
#!/bin/bash
while true
do
sleep 1
 date=`date -d today +"%Y-%m-%d %T"`
 echo ${date} >> /opt/dev/shell/test.txt
done
```

3. 载入配置文件并启动

使用 ```systemctl daemon-reload``` 命令来载入新添加的配置文件,然后使用 ```systemctl start test-sh.service``` 命令启动,再使用 ```systemctl status test-sh.service``` 命令来查看状态,可以看到已经启动,```/opt/dev/shell/test.txt``` 也确实在不停的写入内容,最后使用 ```systemctl stop test-sh.service``` 命令停止服务,可以看到状态也是停止了。注意的是修改配置文件后一定要使用 ```systemctl daemon-reload``` 命令来载入新添加的配置文件,然后再启动服务。```
[root@VM_0_11_centos ~]# systemctl start test-sh.service
^C
[root@VM_0_11_centos ~]# systemctl status test-sh.service
● test-sh.service - test sh log
   Loaded: loaded (/usr/lib/systemd/system/test-sh.service; enabled; vendor preset: disabled)
   Active: activating (start) since Fri 2020-06-26 05:46:45 CST; 11s ago
   Control: 9295 (test.sh)
   CGroup: /system.slice/test-sh.service
       ├─9295 /bin/bash /opt/dev/shell/test.sh
       └─9343 sleep 1

Jun 26 05:46:45 VM_0_11_centos systemd[1]: Starting test sh log...
[root@VM_0_11_centos ~]# systemctl stop test-sh.service
[root@VM_0_11_centos ~]# systemctl status test-sh.service
● test-sh.service - test sh log
   Loaded: loaded (/usr/lib/systemd/system/test-sh.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Fri 2020-06-26 05:47:52 CST; 2s ago
  Process: 9295 ExecStart=/opt/dev/shell/test.sh (code=killed, signal=TERM)

Jun 26 05:46:45 VM_0_11_centos systemd[1]: Starting test sh log...
Jun 26 05:47:52 VM_0_11_centos systemd[1]: Stopped test sh log.
```

查看 Unit 启动日志

Systemd 统一管理了所有 Unit 的启动日志,因此只需要使用 journalctl 命令就可以查看到服务的日志

# 查看所有日志(默认情况下,只保存本次启动的日志)journalctl

# 查看指定时间的日志
journalctl --since="2012-10-30 18:17:16"
journalctl --since "20 min ago"
journalctl --since yesterday
journalctl --since "2015-01-10" --until "2015-01-11 03:00"
journalctl --since 09:00 --until "1 hour ago"

# 显示尾部的最新 10 行日志
journalctl -n

# 显示尾部指定行数的日志
journalctl -n 20

# 实时滚动显示最新日志
journalctl -f

# 查看指定服务的日志
journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
journalctl _PID=1

# 查看某个路径的脚本的日志
journalctl /usr/bin/bash

# 查看指定用户的日志
journalctl _UID=33 --since today

# 查看某个 Unit 的日志
journalctl -u nginx.service
journalctl -u nginx.service --since today

# 实时滚动显示某个 Unit 的最新日志
journalctl -u nginx.service -f

# 合并显示多个 Unit 的日志
$ journalctl -u nginx.service -u php-fpm.service --since today
正文完
 0