【问题标题】:Right way to make a bash script run as a service使 bash 脚本作为服务运行的正确方法
【发布时间】:2020-06-14 22:23:09
【问题描述】:

我有一个监控笔记本电池电量的简单脚本。我如何设置我的 *.service 文件有什么问题,因为我不断收到(code=exited, status=1/FAILURE) 错误。

batterylevel-warning.sh

权限设置为 777。

#!/bin/bash

CRITICAL_PERCENTAGE=`cat /sys/class/power_supply/BAT0/capacity`
STATUS=`cat /sys/class/power_supply/BAT0/status`
ICON="/usr/share/icons/Paper/512x512/status/battery-low.png"

if [ $STATUS == "Discharging" ]; then
    if [ $CRITICAL_PERCENTAGE -eq 20 ]; then
        notify-send -u critical -t 2000 -i $ICON "You need to charge your battery now!!! It is at $CRITICAL_PERCENTAGE%!!!"
    fi
fi

batterylevel.service

[Unit]
Description=Send alerts on low battery starting at 25%.

[Service]
Type=simple
ExecStart=/bin/bash /home/myhome/.scripts/batterylevel-warning.sh

[Install]
WantedBy=multi-user.target

实施

# Create sym link
sudo ln-s /home/myhome/.scripts/batterylevel.service /etc/systemd/system
# Enable and start
sudo systemctl enable batterylevel.service
sudo systemctl start batterylevel.service

问题:当我的电池电量达到 25% 时,我运行 sudo systemctl status batterylevel.service 并得到:

● batterylevel.service - Send alerts on low battery starting at 25%. Designed for silverlance.
   Loaded: loaded (/home/myhome/.scripts/batterylevel.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Mon 2020-03-02 23:04:02 PST; 4s ago
  Process: 5357 ExecStart=/bin/bash /home/myhome/.scripts/batterylevel-warning.sh (code=exited, status=1/FAILURE)
 Main PID: 5357 (code=exited, status=1/FAILURE)

我还在某处运行了sudo systemctl daemon-reload,但仍然没有成功。抱歉,帖子太长了。

【问题讨论】:

  • 您的脚本在手动运行而不是服务时是否有效?
  • 我建议不要依赖这个测试:[ $CRITICAL_PERCENTAGE -eq 20 ]。如果您的电池电量从 21% 下降到 19% 而没有达到 20% 的标记,那么即使您可能想要,您也不会收到通知。您应该解决类似[ $CRITICAL_PERCENTAGE -le 20 ]-le 而不是eq)之类的问题。
  • journalctl -l 是否从您的脚本中给出错误消息?我怀疑它会显示notify-send 命令失败,那是错误值来自
  • @vdavid 是的,当我通过./batterylevel-warning.sh 运行它时,它运行良好。我会试试你所说的关于-le 的使用。 @Jon 我最好检查一下。

标签: bash service systemctl


【解决方案1】:

所以这里有两个问题。

第一个问题是systemd 期望simple 服务永远运行。目前,当您运行 systemctl start 然后终止时,您的脚本只会运行一次。这很好,一些服务以这种方式工作,但我认为这不是你想要的。尝试重新编写脚本以进行投票:

while true; do
    if [ $STATUS == "Discharging" ]; then
        if [ $CRITICAL_PERCENTAGE -eq 20 ]; then
            notify-send -u critical -t 2000 -i $ICON "You need to charge your battery now!!! It is at $CRITICAL_PERCENTAGE%!!!"
        fi
    fi
    sleep 60
done

第二个问题是脚本中的某些内容返回了错误代码。显而易见的候选者是notify-send 命令。 notify-send 不太可能从systemd 联系您的桌面管理员,所以这几乎肯定是问题所在。以下 Stack Exchange 文章描述了有人让 notify-sendcron 下运行时遇到的类似问题。您需要执行类似的操作才能使其在systemd 下运行。也就是说,让systemd 直接与桌面管理员交谈总是很棘手,因此最好使用不同的方法。 https://unix.stackexchange.com/questions/111188/using-notify-send-with-cron

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2023-03-05
    • 2016-09-05
    相关资源
    最近更新 更多