gpt4 book ai didi

linux - bash 脚本中的 While 循环会破坏 systemd 服务

转载 作者:太空狗 更新时间:2023-10-29 12:25:22 25 4
gpt4 key购买 nike

我在使用 Debian,我有一个调用 bash 脚本的 systemd 服务。

该脚本包含一个无限的 while 循环,因为我需要它无限地每隔 X 秒检查一些东西。

一旦遇到“while true; do”行,systemd 服务就会崩溃。

如果我手动执行脚本,脚本运行良好。为什么systemd不喜欢它?我该怎么办?

这是服务和脚本。正如我所指出的,打印“while true; do”之前的 echo 语句。 “while true; do”行后的 echo 语句不打印。

/etc/systemd/system/stream.service:

[Service]
WorkingDirectory=/home/pi/
ExecStart=/home/pi/joi_main.sh
Restart=no
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=stream_service
User=pi
Group=pi
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target

/home/pi/joi_main.sh:

#!/bin/bash -e

today=`/bin/date '+%Y_%m_%d__%H_%M_%S'`
exec 2> "/home/pi/stream_logs/$today.$RANDOM.log"
exec 1>&2

#Wait 120s for system to finish booting
sleep 120

#Initial config
export AUDIODEV=mic_mono
export AUDIODRIVER=alsa
sudo sysctl fs.pipe-max-size=1048576

echo "This line prints"

# Check if video buffer is full every minute. if full, the stream needs to restart
while true; do
echo "This line doesn't"
if grep "100% full" /home/pi/video_buffer_usage.txt; then
echo "Buffer is full!"
# Kill existing processes
pkill -f “raspivid|rec|buffer|ffmpeg”
# Wait 10s
sleep 10
./joi_stream.sh &
fi
sleep 60
done

Journalctl 似乎完全没有帮助,但它就是这样。没有错误。为什么“ session 关闭”?

Mar 31 02:13:41 raspberrypi sudo[1369]: pi : TTY=unknown ; PWD=/home/pi ; USER=root ; COMMAND=/sbin/sysctl fs.pipe-max-size=1048576
Mar 31 02:13:41 raspberrypi sudo[1369]: pam_unix(sudo:session): session opened for user root by (uid=0)
Mar 31 02:13:41 raspberrypi sudo[1369]: pam_unix(sudo:session): session closed for user root

(请不要告诉我为这个 while 循环启动另一个 systemd 服务。我希望它成为这个主脚本的一部分,因为它需要在其他一切之后运行,如果我关闭主服务我也不希望 while 循环运行,因此维护两个 systemd 服务只会增加麻烦。)

最佳答案

./joi_stream.sh 的内容未共享,但我发现您的 systemd 解决方案存在问题。它不能直接解释你的行为,但可能是相关的:

在您的 systemd 配置中,您将 STDOUT 和 STDERR 重定向到 syslog,但在您的脚本中,您将 STDERR(文件描述符“2”)重定向到一个文件,并将 STDOUT(文件描述符“1”)重定向到 STDERR。

exec 2> "/home/pi/stream_logs/$today.$RANDOM.log"
exec 1>&2

如果您的 ./joi_stream.sh 期望您将这些文件描述符重定向到另一个文件,那么它可能不会。如果该文件仅用于日志记录,我会去掉这些行并让 systemd 日志处理它——它会用您的单元标记日志,您可以专门查看您的日志:

 journalctl -u your-unit-name.service

此外,在 systemd 中,您通常不会进入休眠状态等待 systemd 启动。相反,您将使用 .timer 单元。

.timer 文件将指示每分钟运行一次主逻辑,因此不需要“while”循环。计时器单元将包含如下指令:

#开机2分钟后第一次运行 # 之后的每一分钟 OnBootSec=120 OnUnitActiveSec=60

这将是 计时器 单元,启用 以在启动时启动。定时器文件可以非常简单。只需在 /etc/systemd/system 中创建一个 .timer 文件,并将其命名为与您希望它激活的服务文件相同的名称:

[Unit]
Description=Runs my service every minute

[Timer]
# Run for the first time 2 minutes after boot
# and every minute after that
OnBootSec=120
OnUnitActiveSec=60

[Install]
WantedBy=timers.target

要立即启动并测试您的计时器,请运行:

sudo systemctl start my-service.timer

您可以通过以下方式查看计时器的状态:

sudo systemctl list-timers

systemd 解决方案比 rc.local 解决方案更健壮。如果您的 rc.local 解决方案因任何原因终止,它不会重新启动。但是,如果您的脚本将在 systemd 下运行,计时器仍会在一分钟后再次运行它。

关于linux - bash 脚本中的 While 循环会破坏 systemd 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43131432/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com