使用 systemd 在 multi-user.target 之后但在登录屏幕之前执行交互式(whiptail)脚本

pxu*_*xul 6 linux bash systemd

我正在尝试从 Fedora 19 上的 systemd 运行一个小的交互式配置脚本。它必须以 root 身份运行,并在用户登录之前运行。我创建了一个看起来像这样的服务:

[Unit]
Description=blah
Before=graphical.target 

[Service]
Type=oneshot
ExecStart=/path/to/script.sh

[Install]
RequiredBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

为简单起见,脚本如下所示:

#!/bin/sh
whiptail --msgbox "test" 0 78
Run Code Online (Sandbox Code Playgroud)

但是,当我加载此服务并重新启动时,不会显示脚本输出,并且在 /var/log/messages 中它建议应该设置 TERM 变量。但我希望脚本能在第一个虚拟终端上运行。

任何建议或见解将不胜感激。

Jde*_*eBP 1

关于守护进程,您忽略了一个相当基本的事情:作为标准,它们没有控制终端。它们没有终端设备的打开文件句柄。任何想要与“终端”对话的东西都不会这样做。没有“终端”。

不,$TERM没有指定“终端”。它指定终端类型,即作为输出发送并解释为输入的转义序列。这里需要它,您必须安排将其设置为适当的值。但这不是这里的主要因素。主要因素是没有“终端”。

是的,输出结果为/var/log/messages. 默认情况下,服务的标准输出会发送到日志systemd,并且您显然已经运行了syslogd某种类型的日志。您仅在$TERM设置后才看到这一点,这意味着您的脚本已经进一步发展,超越了需要了解终端类型以便计算出如何输出内容的部分。

systemd确实有能力将守护进程附加到终端。它必须有。它agetty作为守护进程运行,在虚拟终端上提供登录会话。

您正在寻找的是StandardInput=StandardOutput=TTYPath=设置,以添加到问题中的该单元文件中。看看/usr/lib/systemd/system/getty@.service它们的使用情况。

您在问题中没有提供足够的信息来说明这是否正是正确的方法,或者您是否应该将 an 添加ExecStartPre=到自定义/etc/systemd/system/getty@.service. 这完全取决于这是在启动 GUI 之前运行一次,还是在每次单独 (TUI) 登录之前运行一次。 Before=graphical.target暗示前者,但这可能不是您真正想要的(鉴于RequiredBy=)。☺