Linux之(17)系统服务

news2025/1/11 23:01:05

Linux之(17)系统服务

Author:onceday Date:2022年12月24日

漫漫长路,有多少人对你笑过…

参考文档:

  • Systemd 入门教程:命令篇 - 阮一峰的网络日志 (ruanyifeng.com)
  • 可能是史上最全面易懂的 Systemd 服务管理教程!( 强烈建议收藏 ) - 腾讯云开发者社区-腾讯云 (tencent.com)

文章目录

      • Linux之(17)系统服务
        • 1.引言
        • 2. systemctl管理服务
          • 2.1 mask强制注销服务
          • 2.2 查看系统上所有服务
          • 2.3 target操作命令
          • 2.4 分析服务之间依赖性
          • 2.5 网络服务和端口的对应关系
        • 3. systemctl配置文件
          • 3.1 service配置文件
          • 3.2 Unit部分参数
          • 3.3 Install部分参数
          • 3.4 Service部分参数
          • 3.5 模板unit文件

1.引言

Unix-like系统,很多功能都是以服务的方式来运行,系统为了某些功能必须要提供一些服务。提供对应service的程序就被称为daemon。

下面是经典的systemd架构图:

在这里插入图片描述

运行服务的进程通常在运行之后,会在在进程名字后面加上一个d(daemon)。例如:

  • atcron,其后面daemon名字会取为atdcrond

目前广泛使用的服务管理机制是systemd,有以下特点:

  • 并行处理所有服务,加速开机流程。让所有的服务可以同时启动。
  • 一经要求就响应的on-demand启动方式。systemd常驻内存,能及时响应启动需求。
  • 服务依赖性的自我检查。会自动启动的当前服务所需的其他服务。
  • 依daemon功能分类。依daemon功能分类。
  • 将多个daemons集合成为一个群组。
  • 向下兼容旧有的init服务脚本。

需要注意以下限制:

  • 如果某个服务启动时管理员自己手动启动,而不是使用systemctl去启动,那么systemd将无法检测到该服务,而无法进一步管理。
  • systemd启动过程中,无法与管理员通过标准输入传入信息,因此,自行编写systemd的启动设置时,务必要取消交互机制。

systemd将每一个daemon执行脚本都称为一个服务单位(unit),而每种服务单位根据功能来区分,就可以分类为不同的类型(type)

基本的类型有如下几种:

  • 系统服务。
  • 数据监听与交换的socket文件服务。
  • 存储系统状态的快照类型。
  • 不同运行级别分类的操作环境。

基本的配置文件放在下面几个目录中:

  • /usr/lib/systemd/system/,每个服务最主要的启动脚本设置,有点类似以前的/etc/init.d下面的文件。
  • /run/systemd/system/,系统执行过程中所产生的服务脚本,这些脚本的优先级要比/usr/lib/systemd/system/高。
  • /etc/systemd/system/,管理员根据主机系统的需求所建立的执行脚本。

/etc/systemd/system/中是操作系统最关注的启动配置,其实际决定那些service启动

具体的执行脚本内容放在usr/lib/systemd/system/中,通过链接来生效

root@ubuntu:~# ll /usr/lib/systemd/system
total 1364
drwxr-xr-x 25 root root 36864 Nov 12 21:07  ./
drwxr-xr-x 16 root root 12288 Feb 22  2022  ../
-rw-r--r--  1 root root   741 Nov  9  2021  accounts-daemon.service
-rw-r--r--  1 root root   115 Nov 28  2019  acpid.path
-rw-r--r--  1 root root   261 Nov 28  2019  acpid.service
-rw-r--r--  1 root root   115 Nov 28  2019  acpid.socket
-rw-r--r--  1 root root  1162 Apr 11  2020  apparmor.service
-rw-r--r--  1 root root   212 Dec  5  2019  apport-autoreport.path
-rw-r--r--  1 root root   242 Dec  5  2019  apport-autoreport.service
......

systemd的unit分类实现很简单,按照上面所示,是通过文件后缀名来分类

扩展名主要服务功能
.service一般服务类型(service unit): 主要是系统服务类型,包括服务器本身所需要的本地服务以及网络服务等,最常见服务类型。
.socket内部程序数据交换的socket服务(socket unit):主要是IPC(Inter-process communication)的传输信息socket文件(socket file)功能。
.target执行环境类型(target unit):其实是一群unit的集合,例如上面表格中谈到的multi-user.target,其本质是一堆服务的集合。
.mount/.automount文件系统挂载相关的服务(automount unit/mount unit):例如来自网络的自动挂载、NFS文件系统挂载等与文件系统相关性较高的进程管理。
.path检测特定文件或目录类型(path unit): 某些服务需要检测某些特定的目录来提供队列服务,例如打印服务,通过检测打印队列目录来启动打印功能。
.timer循环执行的服务(timer unit):这个服务有类似anacrontab,由systemd主动提供。
.swap用于封装一个交换分区或者交换文件,它与mount单元非常类似。
.slice用于控制特定CGroup内(例如一组service与scope单元)所有进程的总体资源。
.scope与service单元类似,但是由systemd根据D-bus接口接收到的消息自动的创建。可管理外部创建的进程。
.snapshot用于表示一个由systemctl snapshot命令创建的systemd units运行状态快照。
.device对于/dev目录下的设备,主要用于定义设备之间的依赖关系。

2. systemctl管理服务

systemctl的参数是非常多的,输入systemctl --help即可查看。

下面是一些常用的命令systemctl [command] [unit]

参数描述
start立刻启动后面接的unit
stop立刻关闭后面接的unit
restart立刻重新启动后面接的unit
reload不关闭后面接的unit的情况下,重新加载配置文件,让设置生效
enable设置下次开机时,后面接的unit会被启动
disable设置下次开机时,后面接的unit不会被启动
status目的后面接的这个unit的状态。
is-active目前有没有正在运行中。
is-enable开机时有没有默认要启用这个unit

可以如下查看某个unit工作的状态:

root@ubuntu:~# systemctl status atd
● atd.service - Deferred execution scheduler
     Loaded: loaded (/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-12-05 23:10:34 CST; 2 weeks 4 days ago
       Docs: man:atd(8)
   Main PID: 687869 (atd)
      Tasks: 1 (limit: 2269)
     Memory: 792.0K
     CGroup: /system.slice/atd.service
             └─687869 /usr/sbin/atd -f
......

第三行的状态有以下的可能性:

  • active(dead),当前是关闭的。
  • active(running),正有一个或多个进程在系统中运行。
  • active(exited),仅执行一次就正常结束的服务,目前并没有任何进程在系统汇总执行。
  • active(waiting),正在运行当中,不过还需等待其他的事件发生才能继续运行。
  • inactive这个服务目前没有运行。

daemon默认状态有如下几种:

  • enabled:这个daemon将在开机时被运行。
  • disabled:这个daemon在开机时不会被运行。
  • static:这个daemon不可以自己启动,不过可能会被其他的enabled的服务来唤醒(依赖属性的服务)。
  • mask:这个daemon无论如何都无法被启动,因为已经被强制注销。可通过systemctl unmask方式改回默认状态。

下面是一个实际操作的例子

root@ubuntu:~# systemctl status nginx.service 
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-10-17 09:25:54 CST; 2 months 7 days ago
......

root@ubuntu:~# systemctl stop nginx.service 
root@ubuntu:~# systemctl status nginx.service 
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Sat 2022-12-24 22:05:26 CST; 2s ago
......
root@ubuntu:~# systemctl disable nginx.service 
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable nginx
Removed /etc/systemd/system/multi-user.target.wants/nginx.service.

可以看到,禁止开机启动,就是从/etc/systemd/system从移除相应的链接文件

2.1 mask强制注销服务

可以通过systemctl mask xxx.service强制注销服务。

root@ubuntu:~# systemctl mask nginx.service 
Created symlink /etc/systemd/system/nginx.service → /dev/null.

原理就是直接将文件链接到空文件上。

取消注销,使用unmask命令即可:

root@ubuntu:~# systemctl unmask nginx.service 
Removed /etc/systemd/system/nginx.service.
root@ubuntu:~# systemctl status nginx.service 
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:nginx(8)

可以看到/etc/systemd/system/路径的优先级比/lib/systemd/system/中要更高。

2.2 查看系统上所有服务

直接使用systemctl就会列出当前系统上的全部unit。常见命令如下:

  • systemctl list-units,显示当前启动的unit,若加上--all会列未启动的unit。
  • systemctl list-unit-files,依据usr/lib/systemd/system内的文件,将所有文件列表说明。
  • --type=TYPE,按unit类型输出,如service/target/socket

示例如下:

列出所有的service

root@ubuntu:~# systemctl list-units --type=service --all
  UNIT                      LOAD      ACTIVE   SUB     DESCRIPTION               
  accounts-daemon.service   loaded    active   running Accounts Service   
......

列出所有的target

root@ubuntu:~# systemctl list-units --type=target --all |cat
  UNIT                 LOAD   ACTIVE   SUB    DESCRIPTION   
  basic.target         loaded active   active Basic System      
  cloud-config.target  loaded active   active Cloud-config availability    
  cloud-init.target    loaded active   active Cloud-init target  
  ......
LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

33 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
2.3 target操作命令

使用systemctl list-units --type=target --all可以列出所有的target unit。

其中几种常见的是:

  • graphical.target,命令行加上图形界面,这个项目已经包含了下面的multi-user.target。
  • multi-user.target,纯命令行模式。
  • rescue.target,在无法使用root登入的情况下,systemd在启动时会多加一个额外的临时系统。
  • emergency.target,紧急处理系统的错误,需要root登录,但是无法使用rescue.target时,可以尝试使用这个模式。
  • shutdown.target,关机模式。
  • getty.target,可设置需要几个tty。

正常使用的模式是multi-user.target以及graphical.target两个模式。

下面命令可修改target配置:

  • systemctl get-default,取得当前的target。
  • systemctl set-default xxx.target,设置指定target为默认target。
  • systemctl isolate xxx.target,切换到后面接的模式。

通常可使用已集成好的命令来操作:

命令描述
systemctl poweroff系统关机
systemctl reboot重新开机
systemctl suspend进入挂起模式
systemctl hibernate进入休眠模式
systemctl rescue强制进入恢复模式
systemctl emergency强制进去紧急恢复模式

挂起模式,即暂停模式:

  • 将系统的状态数据保存到内存中,然后关闭大部分的系统硬件。当用户唤醒机器时,系统数据会从内存中恢复,然后重新驱动被大部分关闭的硬件,并开始正常运行。

休眠模式:

  • 将系统的状态保存到硬盘中,保存完毕后,将计算机关机。唤醒时,从硬盘读取系统状态。
2.4 分析服务之间依赖性

使用list-dependencies列出服务之间的依赖性:

systemctl list-dependencies [unit] [--reverse]

--reverse反向追踪谁使用这个unit。

示例:

root@ubuntu:~# systemctl list-dependencies
default.target
● ├─accounts-daemon.service
● ├─apport.service
● ├─display-manager.service
● ├─e2scrub_reap.service
● ├─kexec-load.service
● ├─kexec.service
● ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
●   ├─apport.service
●   ├─atd.service
●   ├─console-setup.serv
......

查找谁使用了sshd.service这个服务:

root@ubuntu:~# systemctl list-dependencies sshd --reverse
sshd.service
● ├─cloud-init.service
● └─multi-user.target
●   └─graphical.target
2.5 网络服务和端口的对应关系

/etc/service里面存放了各类服务和端口号的对应关系。

root@ubuntu:~# cat /etc/services 
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, officially ports have two entries
# even if the protocol doesn't support UDP operations.
#
# Updated from https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml .
#
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
# If you need a huge list of used numbers please install the nmap package.

tcpmux          1/tcp                           # TCP port service multiplexer
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
......

3. systemctl配置文件

3.1 service配置文件

直接看一下已有的service unit文件,ssh.service

root@ubuntu:~# cat /usr/lib/systemd/system/ssh.service 
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service

配置文件可以分成三个配置区段:

  • Unit,Unit文件通用,用于配置服务的说明和依赖设置。
  • Service/Socket/Timer/Mount/Path,不同的unit类型使用相对应的设置项目。
  • Install,这个项目就是将此unit安装到那个target里面去。

配置文件一般还有以下的规则:

  • 设置项目可以重复,并且后面的设置会替换前面的配置。
  • 如果设置参数有bool参数,可以使用1/0yes/notrue/falseon/off等组合。
  • 空白行、#/;开头的行,都代表注释。
3.2 Unit部分参数

Uint存在隐形依赖,如dbus,会自动添加Requirres=dbus.socketAfter=dbus.socket

socket激活的Service会自动在Socket激活之后再启动,也就是自动将Service添加如.socket单元中的After=。

其可设置参数如下:

  • Description:描述这个unit文件的信息,例如使用systemctl list-units时看到的说明。
  • Documentation:这个项目在提供管理员能够进一步的文件查询功能,可以是如下内容:
    • Documentation=http://www.....
    • Documentation=man:sshd(8)
    • Documentation=file:/etc/ssh/sshd_config
  • After:说明此unit在哪一个daemon启动之后才启动。只是说明服务启动的顺序,并不会强制systemctl去启动其要求的服务,注意和后面requires的区别。
  • Before:与After的意义相反,在某某服务启动前最好启动这个服务。并非强制启动需求。
  • Requires:明确的定义此unit需要在哪个daemon启动后才能够启动,即设置依赖服务。如果要求的服务没有启动,那么该unit便不会启动。
  • Wants:与Requires相似,规范这个unit之后最好还要启动什么服务。并非强制规范,如果要求业务启动失败,也不会影响当前unit。
  • Conflicts:代表冲突的服务,如果这个服务列表里面有启动的服务,那么当前unit就不能启动。
  • Binds to:与Requires相似,如果绑定列表里面任意一个结束或重启,那么当前unit也会跟着结束和重启。
  • Part Of:一个Bind To作用的子集,仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动。
  • OnFailure:当这个模板启动失败时,就会自动启动列出的每个模块。
  • Conditionxxx:当前unit运行必须满足的条件。如ConditionHost=ConditionUser=等。
  • Assertxxx:如果后面条件不满足,就会报错。
3.3 Install部分参数

可设置参数如下:

  • WantedBy:这个设置后面接的大部分是*.target unit,指明这个unit本身是依附于哪一个target unit。通常大多数服务性质的unit都是依赖于multi-user.target
  • Also:当目标这个unit本身被enable时,Also后面接的unitenable的意思。
  • Alias:运行一个链接别名的意思,可以使用别名来操作当前这个unit
3.4 Service部分参数

可设置参数如下:

  • Type:定义启动时的进程行为,对下面的ExecStart会有影响:
    • simple,默认值,由ExecStart接的命令来启动,启动后常驻内存。
    • forking,由ExecStart启动的程序通过spawns扩展出其他子程序来做为此daemon的主要服务。原始的父进程在启动结束之后就会终止运行。
    • oneshot:与simple类似,不过这个进程在工作完毕后就关闭,不会常驻内存。
    • dbus:这个daemon需要获取一个D-Bus的名称之后,才会继续运行,该项目通常要设置BusName=
    • idle:这类daemon通常是开机到最后才执行的服务。
  • EnvironmentFile:可以指定启动脚本的环境配置文件,如EnvironmentFile=-/etc/default/ssh
  • ExecStart:实际执行此daemon的命令或脚本程序。命令串一般只能接受简单的bash命令。
  • ExecStop:与systemctl stop的执行有关,关闭此服务时所运行的命令。
  • ExecReload:与systemctl reload有关的命令操作。
  • Restart:当Restart=1时,则当此daemon服务终止后,会再次启动此服务。
  • RemainAfterExit:当设置为RemainAfterExit=1时,则当这个daemon所属的所有进程都终止后,此服务会再尝试启动,这对于Type=oneshot的服务很有帮助。
  • TimeoutSec:若这个服务在启动或关闭时,因为某些原因导致无法顺利(正常启动或结束),那么timeout之后便强制结束。
  • KillMOde:可以是processcontrol-groupnone其中一种,如果是process则daemon终止时,只会终止主要的进程ExecStart接的后面那串命令。
  • RestartSec:与Restart有相关性,如果这个服务被关闭,然后需要重新启动时,大概要sleep多少时间再重新启动的意思,默认是100ms(毫秒)。

Restart可选参数及其对应启动关系如下:

Restart=noalwayson-successon-failureon-abnormalon-aborton-watchdog
正常退出TT
退出码不为0TT
进程被强制杀死TTTT
systemd操作超时TTT
看门狗超时TTTT
3.5 模板unit文件

可以查看getty@.service,特殊处在于:

root@ubuntu:~# cat /usr/lib/systemd/system/getty@.service 
[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
......
[Service]
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
.....

通过使用getty@tty1/getty@tty2/getty@tty3等方式实例化多个不同的终端。

即上面%I用于替换tty,如getty@tty1,实际执行的ExecStart为:

ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear tty1 linux

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/118178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MergeTree原理之一级索引

一级索引 MergeTree的主键使用PRIMARY KEY定义,待主键定义之后,MergeTree会依据index_granularity间隔(默认8192行),为数据表生成一级索引并保存至primary.idx文件内,索引数据按照PRIMARY KEY排序。相比使…

【PotPlayer】采集Switch图像及录制

【PotPlayer】采集Switch图像及录制下载potplayer使用方法连接设备录制视频无边框设置阳,休,懂?QAQ。阳之前买了个Switch,正好有好玩的想录下来,然后就…自行某宝,某东去买个采集卡。本文只管连软件&#x…

【运维有小邓】ADSelfService Plus身份管理

一、身份管理挑战: 由于企业需要越来越高的安全性,以保护用户帐户免遭入侵者的任何恶意攻击,因此身份管理正日益变得重要。在所有密码相关的身份挑战中,帮助台工作单量成为重中之重,它们在组织的年同比财务预算中不堪…

(二)ElasticSearch使用

一、ES的基本使用 1.创建索引 创建一个test索引http://localhost:9200/test 2.删除索引 http://localhost:9200/test 3.查看索引 http://localhost:9200/_all 4.向索引中新增数据 http://localhost:9200/person/_doc/ 5.搜索数据 http://localhost:9200/person/_doc/_sear…

全志Tina Linux SPINAND UBI 离线烧录 开发指南 支持百问网T113 D1-H哪吒 DongshanPI-D1s V853-Pro等开发板

1 概述 编写目的: 介绍Sunxi SPINand 烧写时的数据布局 2 名词解释 词义UBIunsorted block imagePEBphysical erase blockLEBlogical erase block PEB 和logical block 关系 1 PEB 1 logical block 1 logical block 2 physical blocks3 总体数据布局 ubi 方案…

必读,一文普及MES系统知识

MES系统的基本概念制造执行系统(MES)是一套面向制造企业的信息管理系统。MES系统可以为企业提供管理模块,包括制造数据管理、计划与调度管理、生产调度管理、库存管理、质量管理、生产过程控制、底层数据集成分析、上层数据集成与分解&#x…

LVGL学习笔记5 - Display, Screen和Layer

目录 1. Display 2. Screen 2.1 创建Screen 2.2 加载Screen 2.3 获取活动的Screen 2.4 实例 2.4.1 定义2个Screen全局变量 2.4.2 初始化Screen 2.4.3 循环更替 3. Layer图层 3.1 切换顺序 3.2 顶层和系统层 3.3 实例 3.3.1 创建全局变量 3.3.2 初始化 3.3.3 …

【OpenFOAM】-olaFlow-算例5- oppositeSolitariesFlume

算例路径: olaFlow\tutorials\oppositeSolitariesFlume 算例描述: 两列反向的孤立波相互作用 学习目标: 熟练掌握olaFlow的造波设置,波浪方向与消波方向设置 算例快照: 图1 两列反向孤立波相互作用文件结构&#xff1…

Linux Kernel 远程代码执行漏洞(CVE-2022-47939)

Linux Kernel 远程代码执行漏洞(CVE-2022-47939) CVE-2022-47939 据Security Affairs消息,近期披露的一个严重 Linux 内核漏洞会影响 SMB 服务器,可能导致远程代码执行。 Linux Kernel SMB2_TREE_DISCONNECT 命令处理中存在远程…

C进阶:征服指针之指针与数组强化笔试题练习(2)

🐲🦖 本篇文章是接上篇文章的,上篇文章链接:http://t.csdn.cn/RogqL 目录 🐇🐱一.关于 strlen 函数与数组、指针的综合笔试题 😸T1. 🐆 T2. 🐅T3. 🐲一.关…

网络和通信安全中的SSL/TLS国密改造

2021年3月,国家市场监管总局、国家标准化管理委员会发布公告,国家密码应用与安全性评估的关键标准GB/T39786—2021《信息安全技术信息系统密码应用基本要求》(以下简称“GB/T39786”)正式发布,GB/T 39786是贯彻落实《中…

CSS浮动与CSS定位装饰 Day3

结构伪类选择器 结构伪类 公式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>伪类</title><style>li:nth-child(4n){background-color: red;}</style> </head> <body>…

【记录贴】项目经理的进阶日常:靠年终总结获得了核心项目的机会

进入项目经理这个岗位已经三年了&#xff0c;之前决定转行做项目经理是因为它涉及的知识面广&#xff0c;对个人的成长非常有帮助&#xff1b;也期望未来能积累一些大型且复杂的项目经验、获得更好的升职空间。但现在做了这么久&#xff0c;好像遇到了职业瓶颈&#xff0c;仿佛…

ESP8266 WIFI模块的使用

ESP8266 wiFI 可以用作连接周边的无线设备&#xff0c;也可以作为发送器供其他设备连接通常在产品中&#xff0c;我们经常用作无线的接收使用&#xff0c;也可能会用作在线升级使用等。 说点题外话&#xff1a;虽然在线升级已经较为成熟&#xff0c;但我不推荐在一些重要的产品…

Shell程序编写猜数字的小游戏

文章目录 目录 文章目录 前言 一、设计思路 二、代码编写 三、效果图 总结 前言 在学习Linux课程中学习了一点简单的shell语法&#xff0c;实现了一个猜数字功能的程序。感兴趣的可以看完后自己手动编写玩玩~这个小游戏的编写也是把基础的shell语法基本上都用到了&#…

在QQ音乐巅峰榜年度榜单中,听懂国人2022年的音乐记忆!

拐左为夏&#xff0c;拐右为冬&#xff0c;时至年末&#xff0c;各类形式的年终报告层出不穷。2022年&#xff0c;是特殊的一年&#xff0c;音乐作为不可或缺的一部分&#xff0c;也陪伴广大用户走过了日日夜夜。一首首歌曲拨动着心弦、同时也承载着回忆&#xff0c;熟悉的旋律…

【软件测试】不好,事搞大了,APP测试的血泪教训总结......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 听说&#xff0c;人…

C语言链表-记录学生信息

题目要求&#xff1a; 创建一个 单向链表 来记录学生信息&#xff0c;人数3–5人&#xff1b;链表结点为结构变量&#xff0c;结构的要求如下&#xff1a; struct stu_info{char stu_num[10]; //学号char stu_name[8]; //姓名char stu_sex[2]; //性别int stu_score /…

Flowable学习笔记(二):flowable实战

1.定义流程模板 (1)Call Activity&#xff08;调用活动&#xff09; 在这个流程图中&#xff0c;定义了一个开始节点、调用活动节点和结束节点&#xff08;bpmn.xml文件在文章最后附上&#xff09;。 开始节点&#xff1a;定义了一个执行监听器&#xff08;commonStartExecut…

【MyBatis】进一步理解choose、when、otherwise标签

choose、when、otherwise choose里面包含when、otherwise两个标签&#xff0c;choose是父标签&#xff0c;when和otherwise必须都要写在它里面 当 when 中有条件满足的时候&#xff0c;就会跳出 choose&#xff0c;即所有的 when 和 otherwise 条件中&#xff0c;只有一个会输…