我有一个从 14.04 创建的 nfsroot,我正在使用 16.04 重建它。我的 nfsroot 由三个名为 pc1、pc2 和 pc3 的系统共享。还有 3 个匹配的用户帐户,分别名为 pc1、pc2 和 pc3。
当这些系统启动时,它们会自动登录并随后运行 bash 登录脚本。
在 14.04 中,我在 upstart tty1.conf 文件中替换了 mingetty,如下所示:
# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.
start on stopped rc RUNLEVEL=[2345] and (
not-container or
container CONTAINER=lxc or
container CONTAINER=lxc-libvirt)
stop on runlevel [!2345]
respawn
#exec /sbin/getty -8 38400 tty1
script
exec /sbin/mingetty --autologin `cat /proc/sys/kernel/hostname` --noclear tty1
end script
对我来说,这在 14.04 中运行得很好。它从 /proc 中收集主机名,然后将其用作登录名。
我试图在 16.04 中复制相同的行为,但现在使用 systemd。为此,我修改了 /etc/systemd/system/getty.target.wants。具体来说,我更改了 ExecStart:
ExecStart=-/sbin/agetty -a $HOSTNAME --noclear %I $TERM
但是,通过阅读 systemd 文档和使用一些 google-fu,我了解到在 ExecStart 行中不能使用反引号或环境变量替换。我已测试过对用户帐户进行硬编码,并且它工作正常,但我不知道如何在 systemd 中执行我之前使用 upstart 执行的相同操作。
我也尝试使用一个小脚本来实现此目的,方法是将 ExecStart 行更改为:
ExecStart=/bin/sh -c "/usr/bin/autogetty.sh"
autogetty.sh 脚本是一个简单脚本,用于获取主机名并将其提供给 mingetty。但是它似乎不起作用。我认为问题可能是服务的类型是空闲的,根据我在线的研究,它需要是 fork。我还没有尝试修改服务类型。
我想知道“正确的方法”。到目前为止,我只是在尝试让它发挥作用,即使我让它发挥作用,我也不确定这是否是最好的方法。
谢谢。
答案1
错误观念和错误
我已经了解到我不能在该
ExecStart
行中使用反引号或环境变量替换。
你学到了一个谎言。事实上,文档并没有这么说。你能使用环境变量替换(其语法与大多数 Unix shell 略有不同)。没有HOSTNAME
可以替代的环境变量. 设置这样的环境变量后,不会生成服务进程。
单元文件是可参数化的,并且%H
参数扩展为(动态)主机名,就像过去从文件加载单元时一样。
ExecStart=/bin/sh -c “/usr/bin/autogetty.sh”[…]我还没有尝试修改服务类型。
很好。不要。这样做是错误的。只有forking
当您的服务实际实现了就绪通知协议时才将其更改为。不要将其作为临时解决方案,因为您错误地创建了一个无缘无故分叉的程序。
因为这正是你所做的。不必要的/bin/sh
是分叉一个子进程来运行autogetty.sh
,最终会成为运行该 shell 脚本的第二个 shell 进程。然后第二个 shell 进程分叉以mingetty
作为孙进程运行。这无论如何都不符合分叉就绪协议,因为它依赖于 fork然后在父级中退出。
从 daemontools 的世界吸取教训:服务是运行的,而不是生成的。您运行的程序ExecStart
应该是服务流程,而不是产卵服务流程。
正确的方式
正确的设置方式如下:
- 覆盖模板的特定实例,针对特定的终端设备,而不是整个模板。
- 使用
%H
获取中的主机名ExecStart
。或者使用%m
和机器 ID 作为您的用户帐户名。 - 正确调用事物:
- 直接运行
agetty
即可获得最佳效果。实际上,您根本不需要为所述任务编写任何脚本。 - 如果您仍然选择插入多余的包装脚本:
- 不要使用
/bin/sh -c scriptfile
。只需scriptfile
使用正确指定的脚本解释器制作可执行文件,然后直接运行它。 - 确保您的脚本使用
exec
getty 进程作为守护进程。
- 不要使用
- 直接运行
进一步阅读
- 沃纳·芬克和卡雷尔·扎克。
agetty
.Ubuntu 15.04 手册页。 - https://askubuntu.com/a/659268/43344
- https://unix.stackexchange.com/a/233855/5132
- https://unix.stackexchange.com/a/194218/5132
- 乔纳森·德·博因·波拉德(2015年)。Unix 守护进程的就绪协议问题. 常见问题答案。
- https://unix.stackexchange.com/a/200365/5132
- https://unix.stackexchange.com/a/194653/5132