如何把服务加到systemctl
-------------------------------------------------------------------------------
要将应用(程序 / 脚本)添加到
systemctl 管理,核心是创建一个符合规范的 .service 单元文件(放在 /etc/systemd/system/ 目录下),然后通过 systemctl 命令加载、启用即可。以下是 step-by-step 完整教程,适用于大多数 Linux 发行版(CentOS 7+/Ubuntu 16.04+/Debian 9+ 等)。核心原理
systemd(systemctl 是其命令行工具)通过 “单元文件”(.service)管理服务,文件中定义了服务的启动命令、运行用户、依赖关系、重启策略等。只要按格式编写该文件,systemctl 就能识别并管理你的应用。步骤 1:创建 .service 单元文件
1.1 确定文件路径
单元文件需放在
/etc/systemd/system/(系统级服务,所有用户可用)或 ~/.config/systemd/user/(用户级服务,仅当前用户可用)。推荐用系统级(需 sudo),以 myapp.service 为例(服务名可自定义,如 nginx.service、java-app.service):bash
运行
sudo vim /etc/systemd/system/myapp.service
1.2 编写单元文件(关键!)
根据应用类型(前台运行 / 后台运行、脚本 / 二进制程序),选择对应的模板,替换占位符即可。
模板 1:通用后台服务(最常用,如 Java 程序、Python 脚本、二进制程序)
适用于需要后台运行、意外退出后自动重启的应用:
ini
[Unit]
Description=My Custom Application # 服务描述(自定义,如“我的Java应用”)
After=network.target # 服务启动依赖:网络就绪后再启动(可选,如依赖数据库可加 mysql.service)
[Service]
User=root # 运行服务的用户(建议用普通用户,如 appuser,需提前创建)
Group=root # 运行服务的组(与 User 对应)
WorkingDirectory=/opt/myapp # 应用工作目录(程序/脚本所在目录)
ExecStart=/opt/myapp/start.sh # 启动命令(绝对路径!如:/usr/bin/java -jar app.jar、/usr/bin/python3 script.py)
Restart=always # 重启策略:always(总是重启)、on-failure(失败时重启)、never(不重启)
RestartSec=3 # 重启间隔(秒,如意外退出后3秒重启)
KillSignal=SIGINT # 停止信号(默认即可,无需修改)
[Install]
WantedBy=multi-user.target # 服务安装目标:多用户模式下启动(默认,无需修改)
模板 2:前台运行的服务(如某些无后台模式的程序)
部分程序默认前台运行(不后台 daemonize),需用
Type=simple(默认)或 Type=exec,无需额外配置:ini
[Unit]
Description=Foreground Application
After=network.target
[Service]
User=appuser
WorkingDirectory=/home/appuser/myapp
ExecStart=/home/appuser/myapp/run.sh # 程序前台运行命令
Restart=on-failure
StandardOutput=journal+console # 输出到日志和控制台(可选)
[Install]
WantedBy=multi-user.target
模板 3:带环境变量的服务(如需要自定义 PATH、配置文件路径)
ini
[Unit]
Description=App with Env Vars
[Service]
User=appuser
WorkingDirectory=/opt/myapp
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk" # 环境变量1
Environment="CONFIG_PATH=/opt/myapp/config.yml" # 环境变量2
ExecStart=/usr/bin/java -jar app.jar --config $CONFIG_PATH
Restart=always
[Install]
WantedBy=multi-user.target
关键参数说明(必看!)
| 参数 | 作用 |
|---|---|
ExecStart |
核心!启动服务的绝对路径命令(不能用相对路径,如 ./start.sh 需改为 /opt/myapp/start.sh) |
User/Group |
指定运行服务的用户(避免用 root,需提前创建普通用户:sudo useradd -m appuser) |
Restart |
重启策略:always(推荐,意外退出自动恢复)、on-failure(仅错误退出时重启)、never |
WorkingDirectory |
应用的工作目录(如程序需要读取当前目录下的配置文件,必须指定) |
After |
依赖服务(如依赖数据库,写 After=mysql.service mariadb.service) |
步骤 2:加载并验证服务
2.1 重新加载 systemd 配置
修改 / 创建
.service 文件后,需让 systemd 识别新服务:bash
运行
sudo systemctl daemon-reload
2.2 验证服务文件是否有效
检查配置是否有语法错误(关键!避免启动失败):
bash
运行
sudo systemctl status myapp.service
- 若输出
Loaded: loaded (/etc/systemd/system/myapp.service; disabled; vendor preset: disabled),说明文件无语法错误,已被识别; - 若报错
invalid unit file,需回头检查.service文件的格式(如括号匹配、参数拼写)。
步骤 3:管理服务(启动、开机自启等)
3.1 启动服务
bash
运行
sudo systemctl start myapp.service
(可简写为
sudo systemctl start myapp,.service 后缀可省略)3.2 查看服务状态(确认是否启动成功)
bash
运行
sudo systemctl status myapp
- 若显示
active (running),说明启动成功; - 若显示
failed,查看日志排查错误:sudo journalctl -u myapp -f(-f实时滚动日志)。
3.3 设置开机自启
bash
运行
sudo systemctl enable myapp
- 取消开机自启:
sudo systemctl disable myapp
3.4 其他常用操作
bash
运行
sudo systemctl stop myapp # 停止服务
sudo systemctl restart myapp # 重启服务
sudo systemctl reload myapp # 重载服务(若应用支持热重载,无需停止)
sudo journalctl -u myapp # 查看服务日志(历史)
sudo journalctl -u myapp -f # 实时查看服务日志
常见问题排查
1. 服务启动失败(status 显示 failed)
- 优先看日志:
sudo journalctl -u myapp -f,日志会提示具体错误(如 “文件不存在”“权限不足”); - 检查
ExecStart路径是否正确(用which java/which python3确认命令绝对路径); - 检查工作目录
WorkingDirectory是否存在,运行用户是否有读写权限。
2. daemon-reload 后仍识别不到服务
- 确认
.service文件放在/etc/systemd/system/(系统级)或~/.config/systemd/user/(用户级); - 文件名后缀必须是
.service(如myapp.service,不能是myapp)。
3. 服务启动后立即退出
- 检查应用是否支持后台运行(若前台程序,需用模板 2,无需加
&后台符号); - 调整
Restart=on-failure,并查看日志是否有程序崩溃信息。
示例:添加 Java 应用到 systemctl
假设 Java 程序路径为
/opt/myapp/app.jar,运行用户为 appuser,则 .service 文件如下:ini
[Unit]
Description=Java Application Service
After=network.target
[Service]
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -jar app.jar
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
按步骤执行:
bash
运行
sudo vim /etc/systemd/system/java-app.service # 粘贴上面内容
sudo systemctl daemon-reload
sudo systemctl start java-app
sudo systemctl enable java-app
sudo systemctl status java-app # 验证
只要按模板编写
.service 文件,几乎所有应用都能被 systemctl 管理。如果你的应用有特殊需求(如依赖其他服务、需要自定义停止命令),可以告诉我具体场景,我会调整配置~-------------------------------------------------------------------------------
如何查看 systemctl 的哪些应用
要查看
systemctl 管理的所有应用(即系统服务,.service 单元),可以通过 systemctl 的内置查询命令实现,支持按 “所有服务”“运行中服务”“已启用服务” 等维度筛选。以下是最常用的方法:核心命令:查看所有已安装的服务
bash
运行
systemctl list-unit-files --type=service
说明:
list-unit-files:列出系统中所有 “单元文件”(包括服务、定时器、挂载点等);--type=service:仅筛选 服务类型(排除定时器、挂载点等其他单元);- 输出结果包含 3 列:
UNIT:服务名称(如nginx.service、sshd.service);STATE:服务的 “启用状态”(enabled开机自启、disabled开机不启、masked禁用、static无法手动启动);VENDOR PRESET:系统默认预设状态(通常与STATE一致)。
常用筛选:按 “运行状态” 查看
1. 查看当前正在运行的服务
bash
运行
systemctl list-units --type=service --state=running
说明:
list-units:列出当前 “活跃的单元”(仅显示正在运行 / 激活的服务,而非所有已安装服务);--state=running:仅筛选 运行中 的服务;- 输出会显示服务的 PID、内存占用、启动时间等实时状态。
2. 查看所有 “活跃” 服务(包括运行中、已停止但已激活的)
bash
运行
systemctl list-units --type=service --state=active
3. 查看开机自启的服务
bash
运行
systemctl list-unit-files --type=service --state=enabled
- 仅显示
STATE为enabled(开机自启)的服务,适合检查哪些应用会随系统启动。
4. 查看所有服务(包括活跃 / 非活跃,带详细状态)
bash
运行
systemctl list-units --type=service --all
--all:显示所有服务(包括未运行、已失效的服务);- 适合排查 “已安装但未运行” 的服务(如
STATE为inactive的服务)。
5. 搜索特定服务(模糊匹配)
如果知道服务名称关键词(如
nginx、mysql),用 grep 过滤:bash
运行
# 搜索包含 nginx 的服务(所有已安装)
systemctl list-unit-files --type=service | grep nginx
# 搜索正在运行的包含 ssh 的服务
systemctl list-units --type=service --state=running | grep ssh
6. 简洁查看:仅列出服务名称
如果只需快速获取服务名称(无需状态),可以简化输出:
bash
运行
# 所有已安装服务(仅名称)
systemctl list-unit-files --type=service --quiet
# 正在运行的服务(仅名称)
systemctl list-units --type=service --state=running --quiet
--quiet:仅输出服务名称(如nginx.service),不显示表头和状态列,适合脚本处理。
补充:查看服务详情
如果找到某个服务,想查看其详细信息(启动命令、依赖、日志路径等):
bash
运行
# 替换为具体服务名(如 nginx.service)
systemctl show --all nginx.service
或查看更易读的状态摘要:
bash
运行
systemctl status nginx.service
总结:常用命令速查表
| 需求 | 命令 | |
|---|---|---|
| 所有已安装的服务(含启用状态) | systemctl list-unit-files --type=service |
|
| 当前运行中的服务 | systemctl list-units --type=service --state=running |
|
| 开机自启的服务 | systemctl list-unit-files --type=service --state=enabled |
|
| 搜索特定服务(如 nginx) | `systemctl list-unit-files --type=service | grep nginx` |
| 查看服务详细信息 | systemctl status 服务名.service |
通过以上命令,就能全面掌握
systemctl 管理的所有应用(服务)啦!如果需要进一步操作某个服务(启动、停止、设置开机自启),也可以告诉我~-------------------------------------------------------------------------------
你执行的这条
tcpdump 命令用于抓取指定端口(80、9301、9302)或指定目标主机(11.*.8*)的所有网络流量,并保存到 http_https.pcap 文件中。以下是详细解析和使用说明:命令各部分含义
| 参数 / 选项 | 作用 |
|---|---|
sudo |
以 root 权限执行(抓包需要底层网络权限,普通用户可能失败) |
tcpdump |
核心抓包工具(Linux/macOS 内置,Windows 需用 Wireshark 替代) |
-i any |
监听所有网络接口(any 表示所有网卡,也可指定具体网卡如 eth0、en0) |
"port 9301 or port 9302 or port 80 or host 11.*.8*" |
抓包过滤规则:
or 表示 “或”,满足任一条件即抓取) |
-w http_https.pcap |
将抓包数据保存到文件(-w 表示写文件,pcap 是标准抓包格式,可用于 Wireshark 分析) |
关键注意事项
-
权限要求:必须用
sudo执行,否则会报错tcpdump: permission denied(普通用户无网络抓包权限)。 -
过滤规则说明:你的规则会抓取以下所有流量:
- 所有 80 端口的 HTTP 流量(无论源 / 目标);
- 所有 9301/9302 端口的流量(可能是自定义服务,如 Elasticsearch 集群通信等);
- 所有与 11.*.8* 主机通信的流量(无论端口,包括 TCP/UDP/ICMP 等)。
✅ 若只想抓 “目标是 11.*.8*” 的流量,可改为
dst host 11.*.8*;✅ 若只想抓 “源是 11.*.8*” 的流量,可改为src host 11.*.8*。
-
文件大小与停止抓包:
- 抓包会持续写入
http_https.pcap,直到手动停止(按Ctrl+C); - 若流量大,文件会快速膨胀,建议添加
-G 3600(每小时分割一个文件)或-W 10(最多保留 10 个文件)限制大小,例如:bash运行sudo tcpdump -i any "port 9301 or port 9302 or port 80 or host 11.*.8*" -w http_https_%Y%m%d_%H%M%S.pcap -G 3600 -W 10
- 抓包会持续写入
-
查看抓包结果:
- 实时查看(不保存文件):去掉
-w参数,直接执行:bash运行sudo tcpdump -i any "port 9301 or port 9302 or port 80 or host 11.*.8*" - 分析保存的
pcap文件:用 Wireshark 打开(图形化界面,支持过滤 / 解析协议),或用tcpdump -r http_https.pcap命令行查看。
- 实时查看(不保存文件):去掉
常见问题排查
- 抓不到数据?检查:
- 网卡是否正确(
-i any改为具体网卡,如ip addr查看网卡名); - 过滤规则是否有误(例如端口是否被防火墙拦截,主机 11.*.8* 是否有通信);
- 是否用
sudo执行(无权限会静默失败,不抓包)。
- 网卡是否正确(
- 文件过大?添加
-C 100(每个文件最大 100MB)+-W 5(最多 5 个文件)自动轮转。
-------------------------------------------------------------------------------
linux 前台运行 / 后台运行、脚本 / 二进制程序 的含义
在 Linux 系统中,“前台运行 / 后台运行” 是进程的执行方式,“脚本 / 二进制程序” 是程序的存在形态,二者结合是 Linux 运维 / 开发中最基础的操作场景。下面分维度拆解含义、区别和实操方式,附清晰示例。
一、核心概念总览
| 维度 | 分类 | 核心含义 |
|---|---|---|
| 执行方式 | 前台运行(Foreground) | 进程占用当前终端,终端被阻塞,关闭终端则进程终止 |
| 后台运行(Background) | 进程脱离当前终端的直接控制,终端可继续操作,需特殊处理才能随终端关闭存活 | |
| 程序形态 | 脚本(Script) | 纯文本文件,由解释器(如 bash/python)逐行解析执行(如 .sh/.py 文件) |
| 二进制程序(Binary) | 编译后的可执行文件(如 ls/nginx/ 自定义 C 程序),直接由系统内核执行 |
二、前台运行 vs 后台运行(执行方式)
1. 前台运行(默认方式)
含义:执行程序时,进程与当前终端(Terminal)绑定,终端成为进程的 “控制终端”:
- 终端会实时输出进程的日志 / 信息;
- 终端无法执行其他命令(被阻塞);
- 关闭终端(或按
Ctrl+C),进程会被终止(收到SIGINT信号)。
示例:
bash
运行
# 前台运行 Shell 脚本(阻塞终端,按 Ctrl+C 终止)
./test.sh
# 前台运行二进制程序(如 nginx 前台启动,默认是后台,需加参数)
nginx -g "daemon off;" # nginx 二进制程序前台运行,终端阻塞
2. 后台运行(手动指定)
核心目的:让进程脱离当前终端的阻塞,终端可继续使用;进阶需求是让进程在终端关闭后仍存活(守护进程)。后台运行分两种场景:临时后台(终端关闭则进程终止)、永久后台(终端关闭进程仍运行)。
场景 1:临时后台运行(& 符号)
- 在命令末尾加
&,进程转入后台运行; - 终端可继续输入命令,但进程仍与终端绑定(关闭终端进程终止);
- 用
jobs查看后台进程,fg %n切回前台(n是 jobs 显示的进程编号),kill %n终止后台进程。
示例:
bash
运行
# 后台运行 Shell 脚本(临时)
./test.sh &
# 后台运行二进制程序(如自定义编译的 app)
./myapp &
# 查看后台进程
jobs
# 输出示例:[1]+ Running ./test.sh &
# 将后台进程切回前台
fg %1
# 终止后台进程(方式1:通过 jobs 编号)
kill %1
# 方式2:通过进程 ID(PID),先 ps 查 PID,再 kill
ps -ef | grep test.sh
kill 12345
场景 2:永久后台运行(nohup / 系统服务)
若需要进程在终端关闭 / SSH 断开后仍运行,需脱离终端的控制(成为 “守护进程”),常用两种方式:
方式 1:nohup + &(最常用)
nohup(no hang up):忽略终端关闭的SIGHUP信号,进程不会随终端终止;- 输出默认重定向到
nohup.out,也可手动指定日志文件; - 适用于临时的后台任务(如脚本 / 二进制程序的长期运行)。
示例:
bash
运行
# nohup 后台运行 Shell 脚本,日志输出到 myscript.log
nohup ./test.sh > myscript.log 2>&1 &
# nohup 后台运行二进制程序(如 Java 程序)
nohup java -jar myapp.jar > app.log 2>&1 &
# 说明:2>&1 表示将错误输出(stderr)重定向到标准输出(stdout),最终都写入日志文件
方式 2:系统服务(systemd)(推荐生产环境)
对于需要开机自启、长期稳定运行的二进制程序 / 脚本(如 nginx、mysql、自定义服务),建议注册为系统服务,由
systemd 管理(而非 nohup)。示例:将自定义二进制程序
myapp 注册为系统服务bash
运行
# 1. 创建服务文件(/etc/systemd/system/myapp.service)
cat > /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My Custom Binary App
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp # 二进制程序路径
Restart=always # 进程崩溃自动重启
User=root # 运行用户
StandardOutput=append:/var/log/myapp.log # 日志输出
StandardError=append:/var/log/myapp.log
[Install]
WantedBy=multi-user.target
EOF
# 2. 重载服务配置、启动并设置开机自启
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp
# 3. 查看状态/日志
systemctl status myapp
journalctl -u myapp -f # 实时查看日志
前台 / 后台运行核心区别表
| 特性 | 前台运行 | 后台运行(&) | 后台运行(nohup + &) | 系统服务(systemd) |
|---|---|---|---|---|
| 终端是否阻塞 | 是 | 否 | 否 | 否 |
| 终端关闭进程是否终止 | 是 | 是 | 否 | 否 |
| 日志输出 | 终端 | 终端(可重定向) | 日志文件 | 系统日志 / 自定义文件 |
| 开机自启 | 否 | 否 | 否 | 是 |
| 崩溃自动重启 | 否 | 否 | 否 | 是(配置后) |
三、脚本 vs 二进制程序(程序形态)
1. 脚本(Script)
含义:纯文本文件,包含一系列可执行的命令,需通过解释器(如 bash、python、perl)逐行解析执行,无需编译。核心特征:
- 文本格式,可直接用
cat/vi查看 / 修改内容; - 首行通常用
#!(Shebang)指定解释器(如#!/bin/bash/#!/usr/bin/python3); - 需赋予执行权限(
chmod +x script.sh)才能运行; - 执行效率低于二进制程序(解释器逐行解析)。
常见类型 & 示例:
bash
运行
# 1. Shell 脚本(test.sh)
#!/bin/bash
echo "当前时间:$(date)"
sleep 10
echo "脚本执行完成"
# 赋予执行权限并运行
chmod +x test.sh
./test.sh # 前台运行
nohup ./test.sh & # 后台运行
# 2. Python 脚本(test.py)
#!/usr/bin/python3
import time
print("当前时间:", time.ctime())
time.sleep(10)
print("脚本执行完成")
# 运行方式1:指定解释器
python3 test.py
# 运行方式2:赋予执行权限后直接运行(依赖首行 Shebang)
chmod +x test.py
./test.py
2. 二进制程序(Binary)
含义:源代码(C/C++/Go 等)经编译器编译后生成的可执行文件,直接由 Linux 内核加载执行,无需解释器。核心特征:
- 二进制格式,无法用文本编辑器查看(乱码),需用
file命令识别; - 无需解释器,执行效率极高;
- 通常通过
make/gcc等工具编译生成,或从官网下载预编译包(如 nginx、docker); - 运行时只需赋予执行权限(或直接执行,如系统命令
ls/ps)。
常见类型 & 示例:
bash
运行
# 1. 系统内置二进制程序(如 ls、ps、nginx)
ls -l /bin/ls # 查看 ls 二进制文件
file /bin/ls # 识别文件类型:/bin/ls: ELF 64-bit LSB executable...
# 2. 自定义 C 程序编译为二进制(test.c)
# test.c 内容:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("当前时间:");
system("date");
sleep(10);
printf("程序执行完成\n");
return 0;
}
# 编译为二进制程序 myapp
gcc test.c -o myapp
# 赋予执行权限并运行
chmod +x myapp
./myapp # 前台运行
nohup ./myapp & # 后台运行
脚本 vs 二进制程序核心区别表
| 特性 | 脚本 | 二进制程序 |
|---|---|---|
| 文件格式 | 纯文本(可编辑) | 二进制(不可编辑,乱码) |
| 执行依赖 | 需对应解释器(如 bash/python) | 无需解释器,直接内核执行 |
| 执行效率 | 低(解释器逐行解析) | 高(编译为机器码) |
| 调试难度 | 易(直接看文本内容) | 难(需反编译 / 调试工具) |
| 安全性 | 源码可见,易被篡改 | 源码不可见,安全性更高 |
| 跨平台性 | 好(解释器兼容即可) | 差(需针对不同架构编译) |
| 运行方式 | 需 chmod +x 或指定解释器 | 需 chmod +x 后直接执行 |
四、组合场景实操(高频)
场景 1:后台运行 Shell 脚本并持久化
bash
运行
# 后台运行脚本,日志输出到 /tmp/script.log,终端关闭不终止
nohup /bin/bash /opt/script/backup.sh > /tmp/script.log 2>&1 &
场景 2:后台运行 Go 编译的二进制程序(生产环境)
bash
运行
# 1. 编译 Go 程序为二进制(假设 main.go)
go build -o /usr/local/bin/mygoapp main.go
# 2. 用 nohup 后台运行(临时)
nohup /usr/local/bin/mygoapp > /var/log/mygoapp.log 2>&1 &
# 3. 生产环境推荐:注册为 systemd 服务(开机自启、崩溃重启)
# 参考上文 systemd 示例
场景 3:前台运行二进制程序调试
bash
运行
# 前台运行自定义二进制程序,实时看输出,方便调试(按 Ctrl+C 终止)
./myapp
# 或输出详细日志
./myapp -v # 假设程序支持 verbose 模式
五、常见问题 & 注意事项
-
后台进程日志丢失:
- 后台运行时,若不重定向日志,输出会被丢弃(
nohup默认重定向到nohup.out); - 建议显式指定日志文件(
> log.log 2>&1)。
- 后台运行时,若不重定向日志,输出会被丢弃(
-
脚本执行提示 “Permission denied”:
- 未赋予执行权限,执行
chmod +x script.sh; - 或直接用解释器运行(
bash script.sh),无需执行权限。
- 未赋予执行权限,执行
-
二进制程序提示 “No such file or directory”:
- 不是文件不存在,而是缺少依赖的动态库(如 glibc),用
ldd myapp检查依赖。
- 不是文件不存在,而是缺少依赖的动态库(如 glibc),用
-
后台进程无法终止:
- 先用
ps -ef | grep 程序名查 PID,再执行kill -9 PID(强制终止)。
- 先用
总结
- 执行方式:前台 = 阻塞终端、随终端终止;后台(&)= 不阻塞终端、仍随终端终止;nohup/systemd = 不阻塞、不随终端终止(生产推荐 systemd);
- 程序形态:脚本 = 文本、解释执行、易调试;二进制 = 编译后、直接执行、高效安全;
- 实操核心:临时后台用
&,持久后台用nohup + &,生产环境用systemd;脚本需解释器 / 执行权限,二进制需编译 / 依赖检查。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

浙公网安备 33010602011771号