将旧的 sysvinit 习惯移植到 systemd

将旧的 sysvinit 习惯移植到 systemd

我有一系列脚本,可以用来安装和配置新的 Debian 稳定系统。要自动启动我使用的程序/etc/rc.local,但对于其他情况,我必须手动更改文件/etc/inittab。我还有其他更改,例如添加--noclear到行中1:2345:respawn:/sbin/getty --noclear 38400 tty1

因为我必须自定义关闭过程,所以我最终这样做了:

l0:0:wait:/etc/rc.halt 0
...
l6:6:wait:/etc/rc.halt 6

我的/etc/rc.halt样子是这样的

#!/bin/sh
#   
# rc.halt
#   
# This script is executed when entering level 6/0 (on halt or reboot)

su - teststand -c "/home/teststand/stop_server.sh"  # my custom command

# making sure the halt/reboot process is resumed
test -n "${1}" && /etc/init.d/rc ${1}

exit 0

今天是我第一次安装新的 Debian 8 作为systemd默认初始化系统。我没有考虑这一点,首先对/etc/inittab文件丢失感到惊讶。

在我正在运行的系统(@work 和 @home)上,我仍在运行我的系统,sysvinit这就是为什么我在systemd.

我知道我可以改成旧的sysvinit,但我想看看与systemd.此外,我现在正在定制一个新的安装,我没有太多时间来完成它,这就是为什么我现在没有时间查看文档。

我的问题:有没有一种方法可以快速改变systemd行为,以便我可以添加--nocleargetty用作/etc/rc.halt重新启动/停止的起点?

基本上我可以快速导入我的旧inittab更改吗systemd

谢谢

答案1

systemd 不向后兼容 System 5 init,仅向后兼容 System 5 rc

Linux System 5 风格的系统管理由两部分组成,init它作为进程 #1 运行,rc负责运行启动和停止脚本。它们实际上来自 Debian 中的两个不同的软件包。 init是来自系统维尼特包裹;并且rc通常来自sysv-rc包,但可能来自文件-rc或者开放资源库包裹。

/etc/inittab是经过处理的配置文件init。 systemd 不为此提供任何向后兼容机制。 systemd 的 System 5 向后兼容机制仅适用于 System 5 rc,它运行/etc/init.d/. (这仅适用于 的特定风格rc,而且,systemd 没有为 file-rc 和 openrc 的配置机制实现向后兼容机制。)

这不是 systemd 特有的东西。差不多替换 init/系统管理器(三十年来只有 1 次例外)进程/etc/inittab

要将服务连接到 systemd,您必须使用它所使用的机制支持,即自己的服务单位文件和(通过自动转换为单元文件的生成器). 格式rc的 System 5 配置文件/etc/init.d/

忘记运行级别。

您正在使用的所有运行级别内容在 systemd Linux 操作系统上都已被声明为“过时”。 没有运行级别0或6即可进入。如果没有一些兼容性垫片,它们就不存在。

要使服务在关闭时运行,许多人给出的明显答案是创建一个服务单元,WantedByshutdown.target.不过,这有一些微妙的陷阱。一个更好但不太明显的答案是创建一个正常的服务单元,以DefaultDependencies=yes确保它与关闭目标相冲突,并将服务的核心内容放在 中ExecStop而不是 中ExecStart

[单元]
文档=https://unix.stackexchange.com/questions/233561/

[服务]
类型=一次性
用户=测试台
退出后剩余=true
ExecStart=/bin/true
ExecStop=/home/teststand/stop_server.sh

[安装]
WantedBy=多用户.target

不要在 shell 脚本中创建你自己的穷人守护进程管理程序。

这样的事情总是写得不好。

如果您的“服务”只是运行名为“stop_server.sh”的命令,那么可以推断这是一个在某些手动 shell 脚本服务管理系统下停止服务器的脚本。

就是为了这些写得不好、摇摇欲坠、不可靠、危险的灾难:stop_server.sh stop_server.sh stop_server.sh stop_server.sh stop_server.sh stop_server.sh

你有systemd。 利用它,并使用适当的服务管理机制运行此处运行的任何服务。ExecStop如果您愿意,您根本不需要这种奇怪的服务实际的服务可通过 systemd 运行DefaultDependencies=true,如systemd 将处理关闭服务在关机时间。

在 shell 脚本中采用一个穷人的守护进程主管来“管理”一项服务,然后将其包装在 systemd 服务单元中以提供第二项服务,然后安排在关闭时启动该服务,其目的无非是管理第一个服务并在系统停止或关闭时关闭它,是进入 systemd 恐怖屋的好方法。

世界希望您清洁屏幕。

想要不是正如 Greg Wooledge 和其他人所发现的那样,在注销和随后的登录之间清除虚拟终端实际上​​是逆潮流而行。自 20 世纪 70 年代以来,特权用户或老板的敏感输出在注销后仍然存在,这一直是 Unices(实际上也是其他分时远程访问操作系统)的一个安全问题,并且需要付出很大的努力才能撤消所有这些输出。人们为避免这个问题而投入的东西。

  • 许多系统clear_console的 shell 注销脚本中都有一个标准命令。 (这本身就是有问题的,因为它不能很好地与在内核虚拟终端 #1 上运行的图形程序配合使用,并且不能与任何其他类型的终端(虚拟的或真实的)一起使用。)

    必须删除该命令。

  • 针对虚拟终端的 getty 程序(例如 )的默认设置mingetty是清除终端。 (它在登录之前执行此操作,这意味着如果 TTY 登录服务停止,终端输出可以保持不变。具有讽刺意味的是,此功能本来可以更好地放置在 中login,这要归功于 PAM 的必要性,它在注销时仍在运行。 )

    --noclear必须部署该选项才能禁用此功能。这涉及编写一个或多个单元文件覆盖文件、更改设置ExecStart或简单地指向[email protected]自己设计的本地单元文件。

  • systemd 提供的[email protected]模板服务单元集TTYVTDisallocate=yes指示 systemd 清除内核虚拟终端。 (这又不适用于任何其他类型的终端,甚至用户空间虚拟终端也不起作用,正如其名称所部分反映的那样。)

    这也必须再次使用覆盖或指向的不同服务模板来删除[email protected]

进一步阅读

答案2

我正在使用 CentOS 7,它可能有不同的设置。然而,对我来说,调用getty是由服务文件控制的。 ( 是用于模板化的;它以 开头,字符串被传递到文件中并控制它在哪个 TTY 上运行。)在此文件中,有一行以 开头,它指定命令行。将在此处添加选项。 (最好不要直接编辑下面的文件,因为它可能会被系统升级覆盖;您应该将其复制到first下面的某个位置,可能会隐藏供应商提供的文件。)/usr/lib/systemd/system/[email protected]@[email protected]tty1ExecStart=/usr/etc/etc/systemd/system

看来您想要关闭/重新启动的最好方法不是直接调整关闭/重新启动过程,而是通过将该操作添加到服务关闭操作列表中,该操作systemd将在系统停止或重新启动时自动执行(或当您使用 ) 手动关闭服务时systemctl。完成此操作的快速方法是将脚本转换为一行ExecStop系统服务命令;根据事物的设置方式,您还可以创建一个管理整个事物的用户服务文件并将其放在ExecStop那里。

相关内容