什么是systemd中rc.local的正确替代品,而不是重新创建rc.local的替代品


25

我无法在systemd上找到执行某些本地脚本(或非常本地的命令)的正确方法,我已经知道我一定不能为此类脚本创建服务(在systemd单元中)(否则我必须吗?)。

我发现的解决方法是创建rc.local并赋予其执行权限。

printf '#!/bin/bash \n\nexit 0' >/etc/rc.local 
chmod +x /etc/rc.local

例如,如果我得到一台由您配置的简单rc.local的旧服务器,我将知道您做了什么,以及在发行版上升级或安装新内容会对它造成多大的损害,因为rc.local受外部人员的尊重。软件包,但另一方面,如果我安装服务器并创建一个或两个或三个系统单元(甚至是sysvinit服务),仅仅为了完成一个简单的任务,这有​​时会使您的生活更加艰辛,而这远远超出了我的单元名称有时可能会与发行版开发创建的新服务的名称冲突,并且可能会安装在升级中,从而给我的脚本造成麻烦!

我看到另外一个问题哪里是rc.local中,答案是创造它,并给执行权限,我想我的问题是真的不是一个重复的,因为我不想知道它在哪里-相信我,我只是想要接受过时,但我不能找到做这种事情的正确方法,我应该真正创造一个单元,只是这样一些简单的?


4
systemd“唯一的制胜法宝是不玩”;或者,根据需要,可以创建一个系统单元。我现在可能会使用rc.local,并且在它消失时会在意它。
Rui F Ribeiro

因此,您认为官方方式是创建一个像服务这样的部门?请发布答案作为解决方法。
路西亚诺·安妮丝·马丁尼

1
当我尝试Ubuntu时,我创建了一个Unit,用于在我的桌面上具有持久的ssh-agent缓存,而我没有重新引导,而另一个则用于其他我不记得的事情。您也可以创建一个指向/etc/rc.local的指针,但似乎系统现在正在为您自己做....我暂时会使用rc.local,如果不再使用,请创建一个指向假的指针。 /etc/rc.local然后。
Rui F Ribeiro

这很可能会破坏文档,就好像有些书说您必须在/etc/rc.local中放一些东西,然后尝试升级此文档,例如说rc.local在完全不建议使用时必须标记为可执行文件。该文档已损坏,但是如果您说必须创建一个单元来指向/etc/rc.local,则会破坏文档,因为systemd与您的单元冲突。我相信,如果您是对的,他们可能尚未决定是否弃用该产品,因为他们仍然没有替代品...当他们决定再次破坏所有文档时。
路西亚诺·安妮丝·马丁尼

您需要执行哪种脚本?Systemd有很多单位类型。“服务”只是许多单位类型之一。例如安装单元,自动安装单元,计时器单元,目标单元。其中之一可以解决您的问题吗?
andcoz

Answers:


17

如在其他地方指出的那样,rc-local.service在下使用会变得有点不干净systemd

  1. 从理论上讲,您的发行版可能不会启用它。(我认为这并不常见,例如,因为禁用相同的构建选项也会删除很多人使用的poweroff/ reboot命令)。
  2. 语义并不完全清楚。Systemd定义了rc-local.service一种方法,但是Debian提供了一个插入文件,该文件会更改至少一个重要的设置。

rc-local.service通常可以很好地工作。如果您担心上述情况,则只需复制自己的副本即可!这是魔术:

# /etc/systemd/system/my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/libexec/my-startup-script

[Install]
WantedBy=multi-user.target

我认为您不需要了解每个细节[*],但是在这里您需要了解两点。

  1. 您需要使用启用它systemctl enable my-startup.service

  2. 如果您的脚本依赖于其他任何服务(包括)network-online.target,则必须对其进行声明。例如,添加[Unit]带有线Wants=network-online.target和的部分After=network-online.target

    您无需担心对“早期启动”服务的依赖,特别是之前已订购的服务basic.target。除非设置,否则类似服务会my-startup.service在订购后自动订购。basic.targetDefaultDependencies=no

    如果不确定自己的依赖项之一是否是“早期启动”服务,则一种方法是basic.target通过运行列出之前订购的服务systemctl list-dependencies --after basic.target。(请注意--after,不是--before)。

我认为有一些注意事项也适用于pre-systemd rc.local

  1. 您需要确保您的命令与试图控制同一事物的另一个程序没有冲突。
  2. 最好不要从中启动长期运行的程序,也称为守护程序rc.local

[*]我使用Type=oneshot+ RemainAfterExit=yes是因为它对于大多数单发脚本更有意义。它正式化为您将运行一系列命令,这些命令完成my-startup后将显示为“活动”,并且您将不会启动守护程序。


好吧,有某种“本地”地方可以创建服务或代码片段,或者其他任何东西,或者我可以相信这是本地的并且不应更改?如果我开发自己的守护程序?因为我不想更改系统的独创性,所以当我安装一些apt-get时,由于替换了脚本或类似的东西,我不想看到我的系统着火。我只想相信守护进程将仅启动一次,而无需执行我担心的任何其他疯狂的事情……就像试图将其重新启动为无限(如果它已损坏),等等……
Luciano Andress Martini

1
@LucianoAndressMartini如果您询问启动守护程序的正确方法是什么,则应该为它真正定义一个单独的服务。那可以是一个本机系统.service单元,或者如果您确实想编写LSB初始化脚本,则可以这样做。我不想建议放置几个守护程序rc-local.service或等效的守护程序,我认为它可能有效,但是如果您可以systemctl restart my-daemon像其他任何东西一样重新启动单个守护程序,则看起来会更好。打算将您的本地服务放入/etc/systemd/system
sourcejedi

1
@LucianoAndressMartini您必须避免使用与任何其他服务相同的名称-就像在sysvinit中一样。在类似的情况下,我有时会以local-... 开头我的名字
sourcejedi

1
谢谢!!!半天后保存。这些详细信息对我来说至关重要:Type = oneshot,RemainAfterExit = yes,Wants = network-online.target,After = network-online.target。只需部署apache版本并将静态IP设置为192.168.1.80,这样路由器就可以将流量定向到那里。应该是微不足道的。在Debian9中很烦人。除了“ apt-get apache”,“ systemctl start apache”或带有init.d的说明以外,几乎没有其他在线建议,这些建议都不适用于Debian9下由源代码构建的Apache。
MichaelsonB​​ritt

1
@MichaelsonB​​ritt 最好不要从rc.local启动长期运行的程序,即守护程序。我用过Type=oneshot……它正式化了……您将不会启动守护程序。如果需要有关启动守护程序的信息,请提出一个新问题。
sourcejedi

15

算了rc.local

正如我所说的关于CentOS 7关于Debian 8关于Ubuntu 15的那样

您正在使用systemd + Linux操作系统。 /etc/rc.local是systemd中的双重向后兼容机制,因为它是机制的向后兼容机制,该机制本身就是van Smoorenburg System 5 rc克隆中的兼容机制。

使用/etc/rc.local可能会出错。人们对以下事实感到惊讶:systemd的运行rc.local方式与过去不一样,它们在引导程序中的位置相同。(或者错误地期望:实际上,它并没有在旧系统中运行到最后,正如OpenBSD手册仍然指出的那样。)其他人对于他们为rc.local期待旧的做事方式而设置的事实感到惊讶。然后完全被新的喜欢撤消udev规则,NetworkManager的,systemd-logindsystemd-resolved,或各种“套装” S。

如“ 为什么在安装Arch时`init 0`导致“多余的参数”? ”所示,某些操作系统已经提供systemd 而没有向后兼容功能,例如systemd-rc-local-generatorgenerator尽管Debian仍然保留了向后兼容功能,但是Arch Linux在关闭它们的情况下构建了systemd系统。因此,在Arch和类似的操作系统上,它可能/etc/rc.local 会被完全忽略

算了rc.local。这不是要走的路。您有一个systemd + Linux操作系统。因此,请建立一个适当的systemd服务单元,而不要从向后兼容两个级别的角度出发。(在Ubuntu和Fedora,它是3次来除去,面包车Smoorenburg系统5 rc克隆随后rc.local已经被随后本身两次通过暴发户,然后由systemd取代,在十年前,第一次。)

还要记住迁移到systemd的第一条规则

这甚至不是systemd特有的新想法。在van Smoorenburg rc和Upstart系统上,要做的是制作适当的van Smoorenburg rc脚本或Upstart作业文件,而不要使用rc.local。甚至FreeBSD的手册也指出,如今人们创建了一个合适的Mewburn rc脚本,而不是使用/etc/rc.local。Mewburn rc在2000年由NetBSD 1.5引入。

/etc/rc.local日期可以从Unix第七版开始。1983年,它被AT&T Unix System 3(在AT&T Unix System 5中稍有不同)取代/etc/inittab并基于运行级别。即使是现在,这也是历史。rc/etc/inittab

为您服务管理体系创建适当的本地服务的定义,不管是对的NOSH工具集的一个服务包service-managersystem-control,一/etc/rc.d/对Mewburn脚本rc,用于systemd服务单元文件,新贵一份工作文件,runit / S6 / daemontools的服务目录-encore,甚至是/etc/init.d/van Smoorenburg的脚本rc

在systemd中,此类管理员添加的服务单元文件/etc/systemd/system/通常(或/usr/local/lib/systemd/system/很少)进入。使用nosh服务管理器,/var/local/sv/是本地服务捆绑包的常规场所。Mewburn rc在FreeBSD上使用/usr/local/etc/rc.d/打包的服务单元文件和服务捆绑包(如果要制作)将放在不同的位置。

进一步阅读


2
@LucianoAndressMartini更好的问题是如何在systemd服务中处理rc.local的特定片段。因此,如果您有一个特定的代码段(您提到了一些软件文档中的说明),也许可以发布有关该代码段的问题?有一些通用规则可用于转换,但是您可以通过利用正在运行的软件的功能(例如在前台运行,不尝试守护进程等)来从中获取更多信息,因此请询问具体情况可能会有所帮助。
filbranden

4
您想知道它自1983年以来是否仍然存在贬值,也许它有帮助吗?
丹·卡特

4
这个答案是讲道的,实际上无法回答简单的“我应该做什么琐碎的事情”。它可能包含信息,并提供大量引用,但无法达到stackexchange的目的。
gps

我将这个问题(rc.local的结尾)与dns解决问题一起提出来,作为linux不发展但实际上越来越成为意大利面条代码的原因,systemd已成为许多人的黑匣子。如果用户或管理员希望将某些内容放入rc.local中并且不再使用,则迫使他们首先进行systemd或您讲的其他课程以在几天而不是几分钟内达到相同的最终结果无济于事。当然,白痴可以用一切运作良好且易于使用的东西来做愚蠢的事情,但这绝不是终止它的有效论据。
朱利叶斯

2

https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd的摘要

创建/etc/systemd/system/rc-local.service:

# /etc/systemd/system/rc-local.service
[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

然后:

sudo touch /etc/rc.local
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local

检查:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

由systemd提供的一种用法StandardOutput=journal+console(控制台在您的示例中等同于tty),似乎对于故障排除将更加有用。SysVStartPriority=在某些时候,也不再支持。也许您可以评论有多重要SysVStartPriority=,或者删除它。除此之外,这是一个不错的答案。
sourcejedi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.