通过 bash 脚本使用 systemctl 编辑?

通过 bash 脚本使用 systemctl 编辑?

我经常安装 Debian。为此,我有一个全自动的 preseed.cfg;在预置结束时,它会从我的 TFTP 服务器下载并运行 postinstall.sh 脚本,该脚本会执行一些额外的自定义操作。

我正在从 GNOME 切换到 LXQTE,并使用 SDDM 而不是 GDM。然而,对于我的硬件来说,SDDM 尝试启动得太快。为了解决这个问题,我一直在systemctl edit sddm添加以下内容:

[Service]
ExecStartPre=/bin/sleep 5

这非常有效,我想通过将其添加到 postinstall.sh 脚本来自动化此过程。但是,我不知道如何systemctl edit通过 bash 脚本传递文件内容。我怎样才能做到这一点?

答案1

您可以覆盖$SYSTEMD_EDITOR环境变量运行时使用编辑器以外的其他命令systemctl edit

例如,使用类似的东西SYSTEMD_EDITOR='cp /path/to/source.file'似乎工作正常(尽管它非常丑陋,期望最后一个参数由 systemd 附加到那里!)

对于您的特定情况,您可以使用:

$ { echo "[Service]"; 
    echo "ExecStartPre=/bin/sleep 5";
  } >~/tmp/sddm-override.conf
$ sudo env SYSTEMD_EDITOR="cp $HOME/tmp/sddm-override.conf" systemctl edit sddm

但真正systemctl edit要做的就是在目录下创建一个覆盖文件(在本例中名为 name override.conf/etc/systemd/system/<service>.service.d/,如果该文件不存在,则创建该覆盖文件...因此,直接执行此操作也是一种完全可以接受的方法。 (参见中提到的“插入”和“覆盖”systemd.unit 的手册页更多细节。)

因此,对于您的情况,这将是一个合适的解决方案:

$ sudo mkdir -p /etc/systemd/system/sddm.service.d/
$ { echo "[Service]"; 
    echo "ExecStartPre=/bin/sleep 5";
  } | sudo tee /etc/systemd/system/sddm.service.d/10-startup-delay.conf
$ sudo systemctl daemon-reload

这会在您的设备的“放入”目录中放置一个包含预期内容的文件,在这种情况下,您也可以根据它尝试完成的任务对其进行适当的命名。

更新:正如@GracefulRestart 指出的那样,您需要systemctl daemon-reload在直接添加插件后再进行操作。

答案2

由于我还没有找到如何systemctl edit在脚本中使用,最佳实践是模拟systemctl edit sddm命令并将覆盖放置在 /etc/systemd/system 目录中,因为 /usr/lib/systemd/system 中的服务单元可以更改当包升级时:

UNIT='sddm.service'
DIR="/etc/systemd/system/${UNIT}.d"
mkdir $DIR
echo -e "[Service]\nExecStartPre=/bin/sleep 5" > ${DIR}/override.conf
systemctl daemon-reload

这应该大致相当于systemctl edit sddm正在做的事情。

答案3

你可以改变什么编辑器systemctl(8)其用途edit子命令与SYSTEMD_EDITOR多变的。这本质上构造了一个命令,其最终参数始终是systemctl(8)创建的临时文件,一旦写入,就会移动到override.conf.

正因为如此,我们可以使用tee(1)然后将SYSTEMD_EDITOR我们想要的任何文本从 shell 重定向到systemctl(8)标准输入上的整个命令。例如,重定向此处文档:

SYSTEMD_EDITOR=tee systemctl edit sddm <<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF

/etc/systemd/system/sddm.service.d/override.conf这将创建包含“words”之间内容的嵌入式文件EOF

在幕后,edit子命令看起来像这样:

# Create drop-in directory for service
mkdir -p /etc/systemd/system/sddm.service.d

# Create empty temporary file
touch /etc/systemd/system/sddm.service.d/.

# Pass temporary file as last argument of SYSTEMD_EDITOR
tee /etc/systemd/system/sddm.service.d/.\#override.conf846580011dbe64db/.\#override.conf846580011dbe64db<<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF

# Rename temporary file
mv /etc/systemd/system/sddm.service.d/{.\#override.conf846580011dbe64db,override.conf}

编辑单元后,systemd 配置会自动重新加载(以相当于daemon-reload)。

答案4

我会直接攻击该文件:

sed -i 's/\[Service]/ a\
ExecStartPre=/bin/sleep 5' /usr/lib/systemd/system/sddm.service

相关内容