ghb*_*ann 5 shutdown systemd console
我试图阻止用户在不从机器上物理移除闪存卡的情况下关闭或重新启动。为此,我编写了一个 SystemD 服务,removeflash.service:
[Unit]
Description=Prompt user to remove flash card
[Service]
ExecStop=/usr/lib/systemd/flashshutdown.sh
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Requires=rsyslog.service
Run Code Online (Sandbox Code Playgroud)
flashshutdown.sh是一个bash脚本,如下:
#! /bin/bash
#
while [ -e /dev/flash ] ; do
echo "Please remove flash card"
logger "GHB: Please remove flash card"
sleep 5
done
Run Code Online (Sandbox Code Playgroud)
我没想到 echo 在关闭时会做任何事情,而且它没有。但是,我希望 logger 命令能够工作。没有Requires=rsyslog.service,我的服务在rsyslog.service关闭后就退出了;我插入了防止这种情况发生的要求,但唯一的区别是,removeflash.service 的关闭在关闭顺序中较早。幸运的是,systemd 本身向控制台输出一条消息,表明它正在运行提示用户删除闪存卡的作业,这一事实挽救了该服务的目的。
向控制台发出消息的正确方法是什么?
服务管理下的服务的标准输出和错误(无论是 s6、runit、perp、daemontools、nosh 服务管理还是 systemd)不是控制台。它是连接到某种形式的日志编写器的管道。
对于 systemd 服务,如果您想读取(但不想)以及写入,则需要 .INI 文件中的aTTYPath=/dev/console和 a来更改此设置。见证 systemd 预先提供的.StandardOutput=ttyStandardInput=ttydebug-shell.service
这是一个通用原则,并非 systemd 特定的。守护进程上下文涉及(除其他外)没有控制终端,也没有为终端打开文件描述符,并且在适当的服务管理(例如所有 daemontools 系列)下,这是一个开始的地方,即服务进程开始的状态当主管/服务经理分叉它时。因此,要使用控制台,服务必须显式打开它。
在 systemd 中,上述TTYPath设置StandardInput会导致分叉子进程在正确执行服务程序之前打开控制台。它隐藏在 systemd 内部,您实际上看不到它。在run类似nosh服务的程序中,run程序在执行主程序之前显式地使用一些nosh工具集链加载工具来执行相同的操作(emergency-login在本例中):
% cat /etc/service-bundles/services/emergency-login@console/service/run #!/bin/nosh #紧急超级用户登录控制台 设定值 vc-get-tty 控制台 打开控制 tty vc-reset-tty --硬重置 line-banner“紧急模式登录。” 紧急登录 %
讽刺的是,您不需要该logger命令或任何系统日志依赖项。将这种交互式提示写入日志是没有意义的。但原则上,您确实应该以非特权方式运行此服务。它所做的任何事情都不需要超级用户权限。
#!/bin/bash另一个原则是,除非您确实要使用 Bashisms,否则不要使用您的脚本。过去几十年来,Debian Linux 和 Ubuntu Linux 上系统引导/关闭的最大加速之一是/bin/sh从 Bourne Again shell 切换到 Debian Almquist shell。如果您要编写一个像这样简单的脚本,请使其符合 POSIX 规范并#!/bin/sh 无论如何使用,即使您不使用 Debian/Ubuntu,并且在 Debian/Ubuntu 上您将获得 Debian Almquist shell 的好处作为奖励。
此外,如果您决定使用更多玻璃 TTY 消息,则使用类似 的工具dialog,您将需要设置TERM环境变量,以便您的程序可以查找正确的转义和控制序列以在 terminfo 数据库中发出。再次见证debug-shell.service。(在上述run程序中,为了进行比较,vc-get-tty工具集TERM。)
同样,您将希望记录脚本错误。因此标准错误应该指向带有 的日志StandardError=journal。这是一个 nosh 服务run程序,它说明了与此等效的功能,并且还显示了删除实际上不需要它们的程序的用户权限,在 systemd .INI 文件中将是User=daemon:
% cat /etc/service-bundles/services/monitor-fsck-progress/service/run #!/bin/nosh #用于监视 fsck 进度的本地套接字 本地流套接字监听 --systemd-compatibility --backlog 2 --mode 0644 /run/fsck.progress 设定值 setlogin——守护进程 vc-get-tty 控制台 fdmove -c 4 2 打开控制 tty FD移动 2 4 setuidgid——守护进程 。/服务 %
在这种情况下运行的程序./service在控制台上呈现全屏 TUI,同时其错误被发送到日志记录服务。这是一般在服务管理器下需要做的事情,以便运行服务等程序,与控制台对话。
当然,任何这样的全屏 TUI 程序都会与 systemd 的“A stop job is running”(也写入控制台)发生冲突。但这是你的问题。☺
| 归档时间: |
|
| 查看次数: |
1547 次 |
| 最近记录: |