systemd 和终端启动程序的区别

systemd 和终端启动程序的区别

我很好奇这些程序之间的区别是什么;通过 systemctl 启用时使用 systemd 启动,而/etc/rc.local不是通过 CLI启动。

例如,我最近在树莓派上使用 shairport-sync。最初,我通过 sudo systemctlenabled shairport-sync 将 shairport-sync 设置为启动。

后来,我使用了其中的一个功能shairport-sync来预先运行脚本并发布到连接的设备。

令我惊讶的是,脚本执行时shairport-sync没有kill arecordaplay

但是,当我通过终端运行脚本时,脚本被执行并被杀死,arecord并且aplay.

为了进一步迷惑自己,我shairport-sync通过终端杀死并启动了它,以查看正在发生的事情的输出。当我这样做时,当设备连接并终止时,脚本按照我的预期arecord运行aplay。因此,作为修复,我将其禁用shairport-sync并将其设置为作为快速修复sysmtectl运行。/etc/rc.local之后reboot它的功能正如我所预期的那样。

这让我相信,作为单独运行的程序与通过CLIsystemd启动时运行的程序之间存在一些差异。/etc/rc.local

为什么会发生这种情况?这是因为不同的运行级别吗?一些黑魔法?

设备连接时运行的脚本shairport-sync如下:shairportstart.sh

#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
        /usr/bin/amixer set Speaker 40%
else
        /usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&

exit 0

这是淡入淡出脚本:shairportfade.sh

#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do  
    /usr/bin/amixer set Speaker 1+
done
exit 0

设备断开连接时运行的脚本shairport-sync如下:shairportend.sh

#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0

/var/log/syslog当 shairport-sync 最初作为systemd.何时shairport-sync从 CLI 运行或/etc/rc.local不存在错误。

Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified

请注意,唯一的区别是shairport-sync最初启动的方式,当设备连接或断开连接时shairport-sync继续运行。

答案1

的变体“为什么在 systemd 下事情表现会有所不同?”是一个常见问题。

任何时候从 CLI 而不是从 systemd 运行某些东西时,都会有一些广泛的可能性来解释差异。

  1. 不同的环境变量。记录它在该部分中systemd传递的环境变量man systemd.exec生成的进程中的环境变量。如果您想自己检查差异,可以使用systemd-run /path/to/binary,它将在瞬态范围内运行您的应用程序,就像它由 systemd 服务运行一样。您将得到如下输出Running as unit: run-u160.service:然后您可以journalctl -u run-u160.service查看输出。修改您的应用程序以转储它收到的环境变量,并将 CLI 运行与 systemd 运行进行比较。如果应用程序不方便修改,您只需systemd-run env查看将传递的环境变量并查看生成的日志记录即可。如果您尝试启动 X11 GUI 应用程序,DISPLAY需要设置环境变量。在这种情况下,请考虑使用桌面环境的“自动启动”功能而不是systemd.
  2. 资源限制。看man systemd.resource-control用于限制资源消耗的配置值。用于systemctl show your-unit-unit.service检查影响您尝试启动的服务的完整配置值。
  3. 非交互式外壳。您的bashCLI 环境是交互式登录 shell。它有像以前没有的.bashrc那样的源文件。systemd除了设置环境变量之外,这些脚本还可以执行许多其他操作,例如连接 SSH 代理,以便 SSH 操作不需要登录。也可以看看登录 Shell 和非登录 Shell 之间的区别?
  4. 没有电传打字机。您的交互式会话连接到一些程序喜欢sudossh期望在提示输入密码时使用的 TTY。也可以看看sudo:不存在 tty 且未指定 Askpass 程序
  5. 相对路径与绝对路径。在 shell 中相对二进制工作,但是如记录在man systemd.service,第一个参数必须ExecStart=是二进制文件的绝对路径。
  6. 受限制的命令行语法。 Shell CLI 支持许多元字符,同时systemd命令行语法非常有限。根据您的需要,您可以systemd通过 shell 显式运行命令来复制 Shell 语法:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'

这是系统在具有资源控制的一致环境中运行代码的功能。从长远来看,这有助于获得可重复、稳定的结果,而不会压垮硬件。

相关内容