Linux系统应用--systemd服务(一)


文章摘要:
本文主要描述了systemd服务的应用,从 CentOS 7.x 以后,Red Hat 系列的发行版开始采用systemd的服服务管理模式,该模式支持并行启动,可以加快系统的启动速度。

操作系统: raspbian/debian
硬件平台: 树莓派


服务分类:

.service

一般服务类型,最常见的类型,主要是系统服务,包括服务器本身所需要的本地服务以及网络服务都是,比较经常被使用到的服务大多是这种类型。

.socket

内部程序数据交换的插槽(socket)服务,主要是 IPC (Inter-process communication) 的传输讯息插槽文件 (socket file) 功能。这种类型的服务通常在监控讯息传递的插槽文件,当有透过此插槽文件传递讯息来说要链接服务时,就依据当时的状态将该用户的要求传送到对应的服务,若服务尚未启动,则启动该服务后再传送用户的要求。
使用 socket 类型的服务一般是比较不会被经常用到的服务,因此在开机时通常会稍微延迟启动的时间 。一般用于本地服务比较多,例如我们的图形界面很多的软件都是透过 socket 来进行本机程序数据交换的行为。与早期的 xinetd 这个 super daemon 有部份的相似。

.target

执行环境类型:执行一系列的.service 或.socket 之类的服务的集合,例如 multi-user.target。

.mount
.automount

文件系统挂载相关的服务,文件系统的自动挂载等与文件系统相关性较高的程序管理。

.path

侦测特定文件或目录类型,某些服务需要侦测某些特定的目录来提供队列服务,例如最常见的打印服务,就是透过侦测打印队列目录来启动打印功能! 这时就得要 .path 的服务类型支持了!

.timer

循环执行的服务,有点类似 anacrontab 。


systemctl command 主要有:

start     : 立刻启动服务
stop      : 立刻关闭服务
restart   : 重启服务,相当于先start,再stop
reload    : 重载配置文件,让设定生效(不关闭服务)
enable    : 设定开机时自动启动
disable   : 取消开机时自动启动
status    : 显示服务状态,会列出有没有正在执行、开机预设执行否、登录等信息等
is-active : 显示服务是否正在运行
is-enabled: 显示是否设定了开机启动
mask      :注销服务
unmask    :取消注销状态

其他命令:
列出已安装的服务
systemctl list-unit-files



配置文件各字段说明:

[Unit]

Description

使用 systemctl list-units 时命令时,会输出给管理员看的简易说明,使用 systemctl status 输出的此服务的说明。

Documentation

帮助文档

After

说明此服务是在哪个服务启动之后才启动的,仅是说明服务启动的顺序而已,并没有强制要求。

Before

与 After 的意义相反,是在什么服务启动前最好启动这个服务。仅是规范服务启动的顺序并非强制要求。

Requires

明确的定义此服务需要在哪个服务进程启动后才能够启动,如果在此项设定的前导服务没有启动,那么该服务就不会被启动。

Wants

与 Requires 刚好相反,规范的是这个服务之后最好还要启动什么服务,但Wants后面接的服务如果没有启动,不会影响到这个 服务本身!

Conflicts

冲突的服务,项目后面接的服务如果有启动,那么服务就不能启动。


[Service]

Type

服务启动的方式,对ExecStart有影响

simple默认值,主要由 ExecStart 接的指令串来启动,启动后常驻于内存中。
forking由 ExecStart 启动的程序透过 spawns 延伸出其他子程序来作为主要服务。原生的父程序在启动结束后就会终止运作。 传统的 unit 服务大多属于这种项目,例如 httpd服务,当 httpd 的程序因为运作过久因此即将终结了,则 systemd 会再重新生出另一个子程序持续运作后,再将父程序删除。
oneshot与 simple 类似,不过在工作完毕后就结束了,不会常驻在内存中。
dbus与 simple 类似,必须要在取得一个 D-Bus 的名称后,才会继续运作,因此设定这个项目时,通常也要设定BusName。
idle与 simple 类似,必须要所有的工作都顺利执行完毕后才会执行。通常是开机到最后才执行即可的服务。

EnvironmentFile

指定启动脚本的环境配置文件,Environment后面可接多个不同的 Shell 变量来设定。

ExecStart

启动服务要执行的命令或脚本,可以使用 ExecStartPre (之前)以及 ExecStartPost (之后)两个设定项目来在实际启动服务前,进行额外的指令行为,指令串仅接受『指令 参数 参数...』的格式,不能接受 <, >, >>, |, & 等特殊字符。若要支持比较完整的 bash 语法需要指定Type=oneshot。

ExecStop

关闭服务时所进行的指令。

ExecReload

reload时执行的指令

Restart

Restart=1 时,服务终止后,会再次的启动此服务。

RemainAfterExit

RemainAfterExit=1 时,则当所属的所有程序都终止之后,此服务会再尝试启动。主要与Type=oneshot的服务配合。

TimeoutSec

服务在启动或者是关闭时,因为某些缘故导致无法顺利『正常启动或正常结束』的情况下,进行『强制结束』的超时时间,单位为(毫)秒。

KillMode

process - 服务终止时,只会终止 KillMode 主要的程序 (ExecStart 接的后面那串指令)
control-group - 由此服务所产生的其他control-group的程序,也都会被关闭。
none - 没有程序会被关闭。

RestartSec

服务被关闭后,再重新启动需经等待的时间 ,默认值为100(毫秒)。


[Install]

WantedBy

这个设定后面接的大部分是 *.target, 表示这个服务是附挂在哪一个target底下的,一般来说,大多的服务性质的服务都是附挂在 multi-user.target 底下。

Also

当服务被 enable时,Also 后面接的服务需要(手动)enable。

Alias

别名通过systemctl enable命令操作时,会建立一个别名的软链接。
例如multi-user.target的别名设定为default.target时,就会建立/etc/systemd/system/default.target指向/usr/lib/systemd/system/multi-user.target。


几个重要的目录

/etc/systemd/system - 基本上都是一些软连接,通过管理命令连接的,一般不要手动添加或者删除
/lib/systemd/system - 基本上都在这里了(新建,删除也在这里了)
/usr/lib/systemd/system - 使能的开机自启的服务(硬连接),调用enable/disable命令时创建/删除.


https://cloud.tencent.com/developer/article/1619565

- 阅读全文 -

Linux系统应用--imx8m搭建vnc服务


操作系统: Ubuntu18.04 xfce4桌面系统
硬件平台:imx8m

安装xrdp

# sudo apt-get install xrdp

配置xfce4

# echo "xfce4-session">~/.xsession

修改/etc/xrdp/startwm.sh文件,在./etc/X11/Xsession前一行插入

xfce4-session

重启xrdp

# sudo service xrdp restart

安装vnc4server

# apt-get install vnc4server

设置vncserver的密码

# vncpasswd

启动vnc4server

# vnc4server

如果启动失败,日志提示:

mesg: ttyname 失败: 对设备不适当的 ioctl 操作

root用户修改/root/.profile文件,将/root/.profile文件中的mesg n替换成:

tty -s && mesg n

以下错误不用理会:不影响使用

error opening security policy file /etc/X11/xserver/SecurityPolicy
Could not init font path element /usr/X11R6/lib/X11/fonts/Type1/, removing from list!
Could not init font path element /usr/X11R6/lib/X11/fonts/Speedo/, removing from list!
Could not init font path element /usr/X11R6/lib/X11/fonts/misc/, removing from list!
Could not init font path element /usr/X11R6/lib/X11/fonts/75dpi/, removing from list!
Could not init font path element /usr/X11R6/lib/X11/fonts/100dpi/, removing from list!

安装tightvncserver软件:

apt-get install tightvncserver

设置密码: 可设置无操作权限的密码

# vncpasswd
Password:
Verify:
Would you like to enter a view-only password (y/n)? y
Password:
Verify:

启动服务:

# vncserver

New 'X' desktop is vnvn:1

Starting applications specified in /etc/X11/Xvnc-session
Log file is /root/.vnc/vnvn:1.log

关闭服务:

# vncserver -kill :1

- 阅读全文 -

树莓派笔记--切换声音通道


文章摘要:本文主要描述了如何修改树莓派默认声音输出通道,方法是修改用户家目录下的.asoundrc配置文件即可,主要区别在于 pcm.output字段的不同。


耳机通道输出:

#Analog
pcm.!default {
        type asym
        playback.pcm {
                type plug
                slave.pcm "output"
        }
        capture.pcm {
                type plug
                slave.pcm "input"
        }
}

pcm.output {
        type hw
        card 1
}

ctl.!default {
        type hw
        card 1
}

HDMI通道输出:主要区别在card 0

pcm.!default {
        type asym
        playback.pcm {
                type plug
                slave.pcm "output"
        }
        capture.pcm {
                type plug
                slave.pcm "input"
        }
}

pcm.output {
        type hw
        card 0
}

ctl.!default {
        type hw
        card 0
}

蓝牙耳机通道输出:

# 这一项目貌似大家都一样
pcm.!default {
        type asym
        playback.pcm {
                type plug
                slave.pcm "output"
        }
        capture.pcm {
                type plug
                slave.pcm "input"
        }
}
# 声音输出设备
pcm.output {
        # 类型为蓝牙音频
        type bluealsa
        # 设备为蓝牙音箱的MAC地址
        device "FC:58:FA:E2:E4:3C"
        # 配置文件
        profile "a2dp"
}

# 声音输入设备(树莓派硬件上无输入通道,HDMI也不支持输入)
# 所以只有蓝牙耳机的配置文件才有输入通道
pcm.input {
        type bluealsa
        device "FC:58:FA:E2:E4:3C"
        profile "sco"
}

ctl.!default {
        type bluealsa
}

配置为蓝牙通道后,系统开机后或者蓝牙耳机开机时会自动连接。

- 阅读全文 -

Linux系统应用--CPU内存硬盘使用率


测试系统: Debian

TOP命令: -n 表示只刷新一次

$ top -n 1
top - 16:36:38 up  1:06,  3 users,  load average: 1.95, 1.49, 1.42
Tasks: 180 total,   2 running, 178 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.9 us,  5.7 sy,  0.0 ni, 71.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3854.5 total,   2304.4 free,    832.9 used,    717.1 buff/cache
MiB Swap:    100.0 total,    100.0 free,      0.0 used.   2706.4 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1065 root      20   0  328880  96868  64248 R  81.2   2.5  64:45.65 python3
  671 root      20   0  142680  46616  31008 S   6.2   1.2   1:07.32 Xorg
 6383 pi        20   0   10636   2976   2568 R   6.2   0.1   0:00.03 top
    1 root      20   0   32712   8136   6532 S   0.0   0.2   0:04.94 systemd
    2 root      20   0       0      0      0 S   0.0   0.0   0:00.01 kthreadd
    3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp
    4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp
    8 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 mm_percpu_wq
    9 root      20   0       0      0      0 S   0.0   0.0   0:00.34 ksoftirqd/0

其中第3行 %Cpu(s)表示CPU的使用情况
us - 表示用户空间程序的cpu使用率(user)
sy:表示系统空间的cpu使用率,主要是内核程序 (system)。
ni:表示用户空间且通过nice调度过的程序的cpu使用率。
id:空闲cpu(Idel)
wa:cpu运行时在等待io的时间
hi:cpu处理硬中断的数量
si:cpu处理软中断的数量
st:被虚拟机占用的cpu
71.4 id,表示空闲CPU,即CPU未使用率,100%-71.4%=28.6%,则系统的cpu使用率为28.6%。

其中第4行MiB Mem表示内存占用情况


free命令:

$ free 
              total        used        free      shared  buff/cache   available
Mem:        3946964      851752     2360860      198248      734352     2773204
Swap:        102396           0      102396

打印空闲内存数量:

$ free -m | awk '/Mem/ {print $4}'
2304

-m表示以MB为单位,-G表示以GB为单位


查看磁盘使用情况:
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 19G 6.0G 12G 34% /
/dev/sdb1 20G 4.3G 15G 23% /opt

打印sda1的占用率:

$ df -h | awk '/sda1/ {print $5}'
34%

-h表示采用合适的单位(由于磁盘比较大,经常以GB为单位,以字节计时,数值太大)


基于python的脚本: 实际上仍按上述命令实现

#!/usr/bin/env python3
import os
# 获取CPU温度(仅树莓派支持)
def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    return(res.replace("temp=","").replace("'C\n","")) 
# 获取内存使用情况信息:
def getRAMinfo():
    p = os.popen('free -m')
    i = 0
    while 1:
        i = i + 1
        line = p.readline()
        if i==2:
            return(line.split()[1:4])
# 获取CPU使用情况
def getCPUuse():
    return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip())) 
# 获取磁盘使用情况
def getDiskSpace():
    p =os.popen("df -h /")
    i = 0
    while 1:
        i =i + 1
        line =p.readline()
        if i==2:
            return(line.split()[1:5])
#--------------------------------------------------------------
CPU_temp=getCPUtemperature()
CPU_usage=getCPUuse()
RAM_stats = getRAMinfo()
#RAM_total = round(int(RAM_stats[0]),1)
#RAM_used  = round(int(RAM_stats[1]),1)
#RAM_free  = round(int(RAM_stats[2]),1) 
RAM_total = RAM_stats[0]
RAM_used  = RAM_stats[1]
RAM_free  = RAM_stats[2]
DISK_stats = getDiskSpace()
DISK_total = DISK_stats[0]
DISK_used  = DISK_stats[1]
DISK_perc  = DISK_stats[3] 

if __name__ =='__main__':
    print('CPU Temp   = '+CPU_temp)
    print('CPU Use    = '+CPU_usage)
    print('RAM Total  = '+str(RAM_total) +'MB')
    print('RAM Used   = '+str(RAM_used)  +'MB')
    print('RAM Free   = '+str(RAM_free)  +'MB')
    print('DISK Total = '+str(DISK_total)+'B')
    print('DISK Used  = '+str(DISK_used) +'B')
    print('DISK Usage = '+str(DISK_perc))

基于C语言的方法:

#include <stdio.h>
#include <string.h>
#define CPU_IDEL_CMD    "top -n 1 | awk '/Cpu/ {print $8}'"
#define MEM_FREE_CMD    "free -m  | awk '/Mem/ {print $4}'"
int main(int argc, char *argv[])
{
    FILE* fp;
    char buff[100];
    fp = popen(MEM_FREE_CMD,"r");
    bzero(buff,100);
    fread(buff, 1, 50, fp);
    printf("%s", buff);
    fclose(fp);
    return 0;
}

- 阅读全文 -


Copyright©2025 春天花会开, All Rights Reserved. Email: webmaster@oroct.com