想知道服务的真实启动命令?试试systemctl show -p ExecStart 服务名吧!systemd会解析.service文件里的ExecStart=字段哦。再结合systemctl cat,就能读取完整的unit定义啦。不过要注意,环境变量得去对应的配置文件里查哦。

systemd 系统:用 systemctl show 查服务的真实启动命令
systemd 不直接执行 shell 脚本,而是解析 .service 文件里的 ExecStart= 字段。想看到某服务实际跑的是哪条命令,不能只看 systemctl status 的摘要,得查原始定义:
systemctl show -p ExecStart 服务名—— 显示启动命令(含参数),比如systemctl show -p ExecStart sshd输出ExecStart=/usr/sbin/sshd -D $SSHD_OPTSsystemctl cat 服务名—— 直接打印该服务的完整 unit 文件,能看清EnvironmentFile、ExecStartPre等所有执行环节- 注意:
ExecStart可能引用环境变量(如$SSHD_OPTS),真实命令需结合/etc/sysconfig/sshd或/etc/default/sshd查值
SysVinit 系统:/etc/init.d/ 脚本里找 start) 分支
CentOS 7 以前或 Debian 9 之前的老系统,服务靠 /etc/init.d/ 下的 shell 脚本控制。关键不是脚本本身,而是它内部怎么定义启动逻辑:
- 打开脚本(如
sudo vim /etc/init.d/nginx),搜索start)这个 case 分支 —— 真正的启动命令就写在里面,常见形式是daemon --user $NGINX_USER $NGINX_BIN -c $NGINX_CONF_FILE - 别只看开头的
DAEMON=变量,很多脚本会动态拼接参数(比如检查/etc/default/nginx是否存在并 source 它) - 运行
sudo /etc/init.d/nginx start实际执行的就是这个分支里的全部逻辑,包括预检、权限切换、后台化等
/etc/rc.local 是最直白的开机命令入口,但默认可能不执行
这个文件本意是让用户加自定义命令,但它在 modern systemd 系统里默认被禁用,且执行时机晚于多数服务 —— 很多人以为写了就生效,结果发现命令根本没跑:
- 先确认是否启用:
sudo systemctl status rc-local,如果显示inactive (dead),说明没激活 - 启用方式:确保
/etc/rc.local有可执行权限(sudo chmod +x /etc/rc.local),且第一行是#!/bin/bash;然后运行sudo systemctl enable rc-local - 注意:该文件里写的命令没有 systemd 的依赖管理能力,比如想等网络就绪再运行
curl,得自己加until ping -c1 google.com; do sleep 1; done,否则容易失败
别漏掉 /etc/systemd/system/multi-user.target.wants/ 这类符号链接
systemd究竟启动了哪些服务,不能仅看systemctl list-unit-files这一命令的结果,更重要的是要明确「究竟是哪个target将其拉起」。即便某个服务处于enabled状态,也有可能因为对应的target未被激活而根本不会启动:
ls -l /etc/systemd/system/multi-user.target.wants/—— 这里列出的都是真正会在 multi-user(即命令行模式)下自动启动的服务链接- 每个链接指向
/usr/lib/systemd/system/xxx.service或/etc/systemd/system/xxx.service,后者优先级更高,覆盖前者 - 如果你手动
systemctl enable xxx,本质就是在这里建个链接;删掉链接 ≠ disable,得用systemctl disable xxx才干净
systemctl show -p ExecStart 和 systemctl cat 组合用最稳;SysVinit 下必须进 start) 分支看,光看变量名会误判;/etc/rc.local 容易被忽略启用状态;而 .wants/ 目录才是服务实际被拉起的“证据链”终点。