news 2026/9/24 17:12:57

银河麒麟 V10 服务开机起不来?unit 文件照抄 + 五步定位,203 报错一次解决

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
银河麒麟 V10 服务开机起不来?unit 文件照抄 + 五步定位,203 报错一次解决

自己写的服务交给 systemd 管,一启动就给你这么一行:

Job for myapp.service failed because the control process exited with error code. See "systemctl status myapp.service" and "journalctl -xe" for details.

点开 status 看,最后一行是code=exited, status=203/EXEC。你检查了脚本路径,明明存在,手动跑也正常,可 systemd 就是起不来。

另一种更气人的情况:服务能手动起来,enable也执行成功了,重启之后它压根没自启。

这两类故障占了 systemd 排错的一大半。下面按报错码对号入座。

一、先看它死在哪一步

别急着改 unit,先把真正的报错挖出来:

systemctl status myapp-l--no-pager journalctl-umyapp-b--no-pager

这两条里status=203/EXEC那个数字是关键,它直接告诉你死因:

退出状态真实含义最常见的锅
203/EXEC执行不了路径写错、没执行权限、脚本首行 shebang 错
217/USER用户不对User=指定的用户不存在
200/CHDIR工作目录不对WorkingDirectory=指向的目录不存在
status=1/FAILURE程序自己退了程序内部报错,看程序自己的日志
timeout启动超时Type=forking但程序没 fork,或启动太慢
start request repeated too quickly反复重启被掐程序秒退,Restart=always触发了启动频率限制

顺手做个语法体检,能提前抓出拼错的指令:

systemd-analyze verify /etc/systemd/system/myapp.service

没输出就是语法没问题。有输出会直接指出哪一行有问题。

二、对着原因改 unit 文件

报 203/EXEC

三个原因,按这个顺序查:

# 1. ExecStart 里的路径写全了吗(systemd 不认相对路径)whichpython3 systemctlcatmyapp|grepExecStart# 2. 文件有执行权限吗ls-l/opt/myapp/start.shsudochmod+x /opt/myapp/start.sh# 3. 脚本第一行的 shebang 对吗head-1/opt/myapp/start.sh

有坑:systemd 不会帮你展开~$HOME这类变量,也认不了相对路径。ExecStart里一律写绝对路径。

有坑:脚本在 Windows 上编辑过,行尾是 CRLF,shebang 变成#!/bin/bash\r,bash 找不到,直接 203。用file start.sh能看到CRLF line terminators,修一下:

sed-i's/\r$//'/opt/myapp/start.sh

程序其实起来了但 systemd 报超时

这是Type=设错了。前台运行的程序用默认的simple,会自己 fork 到后台的老程序要用forking

[Service] Type=forking PIDFile=/var/run/myapp.pid

有坑Type=forking必须配PIDFile,否则 systemd 找不到主进程,会误判成启动失败。反过来,前台程序错设成forking,systemd 会一直等到超时。

依赖的服务还没起来就抢跑

[Unit] After=network.target postgresql.service Wants=postgresql.service

After只管顺序,Wants才是真去拉起依赖。用Requires的话依赖挂了自己也跟着挂,一般服务用Wants更稳。

有坑After=network.target只表示网络服务管理器起来了,不代表网卡已经拿到 IP。要等真正联网,用network-online.target并配合Wants=network-online.target

程序秒退,想让它自动拉起来

[Service] Restart=on-failure RestartSec=5 StartLimitIntervalSec=0

Restart=on-failure表示非正常退出才重启,always是退出就重启(包括你手动 stop 的情况,慎用)。

有坑StartLimitIntervalSec默认 10 秒内最多启动 5 次,超了就报start request repeated too quickly并且不再尝试。程序启动慢的话把它设成 0(不限)或者调大。

需要环境变量

[Service] Environment="JAVA_HOME=/usr/lib/jvm/java-11" EnvironmentFile=/etc/myapp/env.conf

EnvironmentFile里按KEY=value一行一个写。

三、能跑起来之后,让它开机自启

sudosystemctl daemon-reload# 改了 unit 文件必须跑这条sudosystemctlenable--nowmyapp# 设自启 + 立刻启动systemctl is-enabled myapp

is-enabled的几种输出,含义不一样:

输出状态怎么办
enabled已自启正常
disabled未自启systemctl enable myapp
static不能自启,只能被别人拉正常,检查是谁 Wants 它
masked被彻底屏蔽systemctl unmask myapp

有坑masked状态很多人不知道怎么来的,通常是之前有人执行过systemctl mask。它比disable更狠,连手动 start 都不行,必须unmask才解。

有坑:改了 unit 文件不跑daemon-reload,systemd 用的还是内存里的旧版本。你改半天没效果,八成卡在这一步。

四、enable 成功但重启后没起来?查这三处

1. WantedBy 跟当前 target 对不上

systemctl get-default systemctlcatmyapp|grepWantedBy

服务器版默认multi-user.target,桌面版默认graphical.target。unit 里写WantedBy=graphical.target而机器跑在multi-user.target上,就不会自启。

最稳的写法是:

[Install] WantedBy=multi-user.target

multi-user.target在桌面版上同样会被拉起。

2. 服务是 socket 激活的

有些服务没有 service 在跑,靠.socket单元守着端口,来请求才拉起:

systemctl list-units--type=socket--all|grepmyapp

这种情况systemctl status myapp.service显示 inactive 是正常的,看 socket 单元就行。

3. 开机太早,依赖的东西还没就绪

启动时磁盘还没挂载完、网络还没通。加上:

[Unit] After=network-online.target remote-fs.target Wants=network-online.target

想看服务是不是拖慢了开机,用这条:

systemd-analyze blame|head-20

五、防复发:unit 文件交付前过一遍清单

写完 unit 别直接上生产,对着这份清单过一遍:

cat>~/checkunit.sh<<'EOF' #!/bin/bash U=$1 echo "== 语法体检 ==" systemd-analyze verify /etc/systemd/system/$U 2>&1 | head -10 echo "== ExecStart 是否绝对路径 ==" systemctl cat $U | grep -E '^ExecStart' | grep -v '^ExecStart=/' && echo "有相对路径,改掉" || echo "OK" echo "== 执行权限 ==" P=$(systemctl cat $U | grep -m1 '^ExecStart=' | sed 's/ExecStart=//' | awk '{print $1}') [ -x "$P" ] && echo "OK: $P 可执行" || echo "有问题: $P 不可执行或不存在" echo "== WorkingDirectory 是否存在 ==" W=$(systemctl cat $U | grep -m1 '^WorkingDirectory=' | cut -d= -f2) [ -z "$W" ] || { [ -d "$W" ] && echo "OK: $W" || echo "有问题: $W 不存在"; } echo "== 自启状态 ==" systemctl is-enabled $U 2>&1 EOFchmod+x ~/checkunit.sh

用法:./checkunit.sh myapp.service

还有一条经验:别直接改/usr/lib/systemd/system/里的 unit。那个目录是软件包装的,系统升级会被覆盖。要改就复制到/etc/systemd/system/再改,/etc下优先级最高。


附:unit 文件结构与指令速查

unit 三段结构:

[Unit] Description=服务说明 After=network.target # 启动顺序:在谁之后 Wants=postgresql.service # 弱依赖:会去拉起,对方挂了不影响自己 Requires=postgresql.service # 强依赖:对方挂了自己也挂 [Service] Type=simple # simple(前台) / forking(后台,需PIDFile) / oneshot / notify User=appuser WorkingDirectory=/opt/myapp Environment="KEY=value" EnvironmentFile=/etc/myapp/env.conf ExecStart=/opt/myapp/start.sh ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure # no/on-success/on-failure/on-abnormal/always RestartSec=5 StartLimitIntervalSec=0 [Install] WantedBy=multi-user.target # 服务器版与桌面版通用的自启目标

常用指令:

systemctl daemon-reload 改完 unit 必跑 systemctl enable --now 服务 设自启并立刻启动 systemctl disable --now 服务 取消自启并停止 systemctl is-enabled 服务 查自启状态 systemctl mask / unmask 服务 彻底屏蔽 / 解除屏蔽 systemctl cat 服务 看最终生效的 unit 内容 systemd-analyze verify 文件 unit 语法体检 systemd-analyze blame 看谁拖慢了开机 journalctl -u 服务 -b 看本次启动的日志

systemd 排错其实有固定套路:看status=后面的退出码,按码找原因,改完daemon-reload。大部分人卡住是因为只盯着Job failed那句提示,没往下看状态码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 17:08:38

RVC变声器实战入门:用10分钟语音练出你的第一个AI音色

RVC变声器实战入门&#xff1a;用10分钟语音练出你的第一个AI音色 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Convers…

作者头像 李华
网站建设 2026/9/24 17:08:09

3 步搞定:国家中小学智慧教育平台电子课本下载工具使用指南

3 步搞定&#xff1a;国家中小学智慧教育平台电子课本下载工具使用指南 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具&#xff0c;帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载&#xff0c;让您更方便地获取课本内容。 项目…

作者头像 李华
网站建设 2026/9/24 17:03:46

30 分钟配好 Continue:JetBrains 插件安装、离线构建与调参指南

30 分钟配好 Continue&#xff1a;JetBrains 插件安装、离线构建与调参指南 【免费下载链接】continue open-source coding agent 项目地址: https://gitcode.com/GitHub_Trending/co/continue 写代码时总要切到网页版 AI 问一句&#xff0c;答完再切回来贴代码&#xf…

作者头像 李华