为什么 systemctl restart 不用写 .service?

来源:网络 点击数: 发布时间:2026年09月04日

刚接触 Linux 时都会这样写:

systemctl restart nginx.service

但很多教程却写成:

systemctl restart nginx

而且同样能正常工作。

这是为什么?

一、因为 systemd 会自动补全 .service

在 systemd 中,所有管理对象都叫 Unit(单元)。

常见的 Unit 类型有:

类型
后缀
服务
.service
定时任务
.timer
套接字
.socket
挂载点
.mount
目标组
.target
路径监控
.path

当你执行:

systemctl restart nginx

systemd 会自动理解为:

systemctl restart nginx.service

所以两种写法完全等价。

例如:

systemctl status ssh

等同于:

systemctl status ssh.service
systemctl restart abc

等同于:

systemctl restart abc.service

对于服务(service)来说,写不写扩展名都可以。

二、哪些命令也能省略扩展名?


不仅是 restart。

大部分 systemctl 命令都支持:

systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx
systemctl enable nginx
systemctl disable nginx
systemctl status nginx
systemctl cat nginx

实际上都在操作:

nginx.service

因此运维人员平时通常都懒得写 .service。

三、什么时候不能省略?


当存在多个同名 Unit 时。

例如系统里同时有:

foo.service
foo.socket
foo.timer

此时:

systemctl status foo

systemd 无法准确判断你要查看哪个对象。

因此应该明确指定:

systemctl status foo.service
systemctl status foo.socket
systemctl status foo.timer

这样最安全。

四、Unit 文件里不能偷懒

很多人以为既然命令行能省略,那么配置文件里也能省略。实际上不行。

例如:

[Unit]
After=network-online.target
Requires=abc.service

这里必须写完整名称。

因为 systemd 在解析依赖关系时,需要明确知道对象类型。

如果写:

Requires=abc

systemd 会直接报错。

所以:

  • 命令行可以偷懒
  • Unit 配置文件不能偷懒

五、一个很多人不知道的细节

不仅 .service 可以自动补全。

下面这些也可以:

systemctl start fstrim.timer

可以写成:

systemctl start fstrim

systemd 会自动找到对应的 Unit。

不过运维圈通常有个习惯:

  • Service 经常省略后缀
  • Timer、Socket、Mount 通常写全后缀

因为这样可读性更好。

例如:

systemctl status nginx

一眼就知道是服务。

但:

systemctl status fstrim

别人未必知道你查看的是 Timer 还是 Service。

因此很多管理员会写:

systemctl status fstrim.timer

让含义更加明确。

总结

在命令行里,systemctl 默认会把没有后缀的名称当成 .service 处理;而在 Unit 配置文件中,必须写完整的 Unit 名称。

所以:

systemctl restart nginx

和:

systemctl restart nginx.service

本质上没有任何区别。