Linux service 命令使用技巧

3次阅读

service命令常报command not found,因现代linux多用systemd,service仅为兼容层;debian/ubuntu需安装sysvinit-utils,centos/rhel 8+依赖systemd-sysv-generator桥接;应优先使用systemctl。

Linux service 命令使用技巧

service 命令为什么找不到或报错 command not found

因为 service 是 SysV init 系统的命令,现代大多数 Linux 发行版(如 Ubuntu 20.04+、CentOS 8+、Fedora 29+)默认用 systemd,service 只是兼容层脚本,可能未安装或不在 PATH 中。

  • Debian/Ubuntu 上它属于 sysvinit-utils 包,精简系统(如 docker 镜像、cloud-init 最小安装)常被剔除,运行 apt install sysvinit-utils 才能用
  • CentOS/RHEL 8+ 中 service 被移到 systemd-sysv-generator 自动桥接,但若服务没提供 SysV 兼容脚本(即没有 /etc/init.d/xxx),直接调用会提示 Unit xxx.service could not be found
  • 别在脚本里硬依赖 service——它不保证存在;生产环境建议统一用 systemctl

service nginx start 和 systemctl start nginx 有啥区别

表面看效果一样,实际背后机制完全不同:前者调用 /etc/init.d/nginx 脚本(如果存在),后者直接与 systemd daemon 通信,走 unit 文件定义的完整生命周期管理。

  • service 不读取 nginx.service 中的 Restart=alwaysLimitNOFILE 等配置,只执行脚本里的 start 函数逻辑
  • 如果 /etc/init.d/nginx 是旧版手写脚本,可能忽略 systemd 的 cgroup 隔离,导致 systemctl status nginx 显示 inactive(进程活着但没被 systemd 追踪)
  • 某些发行版(如 Ubuntu)的 service 实际是 shell wrapper,会尝试 fallback 到 systemctl,但 fallback 规则不透明,比如带参数时(service nginx reload)可能失败

用 service 查看服务状态时为什么总显示 “unknown”

这是 service 尝试解析 /etc/init.d/xxx 脚本中的 status 函数失败导致的,不是服务真挂了。

  • 常见原因:脚本里用 pidofps | grep 判断进程,但进程名和脚本预期不一致(比如 nginx 主进程叫 nginx: master process,而脚本只查 nginx
  • 另一个坑:service xxx status 不等价于 systemctl is-active xxx——前者只输出文本,后者返回 0/1 退出码,脚本里用 $? 判断会出错
  • 更可靠的做法是绕过 service,直接用 systemctl is-active --quiet nginx && echo "running",或者看 systemctl show -p SubState nginx

想让 service 命令支持自定义服务怎么办

不能只丢个二进制进去就完事,service 强依赖 /etc/init.d/ 下的可执行脚本,且该脚本必须实现标准函数接口startstopstatusrestart)。

  • 脚本第一行必须是 #!/bin/sh(不是 #!/usr/bin/env bash),否则 service 调用时可能解析失败
  • 必须包含 ### BEGIN INIT INFO 注释块(即使空),否则 update-rc.dchkconfig 无法注册开机启动项
  • 别在脚本里用 systemctl 混合调用——比如 start() 函数里写 systemctl start myapp,会导致双重管理、pid 文件冲突、信号丢失

现在写新服务,直接写 .service 文件放 /etc/systemd/system/,然后 systemctl daemon-reload,比折腾 /etc/init.d/ 更稳。老系统迁移时,service 只是过渡工具,别当主力。

text=ZqhQzanResources