所以我有一个 bash 脚本,如果电池电量低,它会通知我。
脚本在这里
#!/bin/bash
BATTERY=$(upower -e | grep 'BAT')
while :
do
BATTERY_PERCENTAGE=$(upower -i $BATTERY | grep percentage | awk '{ print $2 }' | sed s/'%'/''/g)
CABLE=$(upower -d | grep -n2 line-power | grep online | awk '{ print $3 }')
if [[ "$BATTERY_PERCENTAGE" -lt "10" && $CABLE = "no" ]]; then
notify-send --urgency=critical "WARNING: Battery is about to die" "Plug in the power cable"
fi
sleep 60
done
所以我目前正在使用dwm
窗口管理器Arch Linux
。问题是,如果我只是关闭窗口管理器,然后再次启动它,它实际上会关闭我正在使用的所有程序(例如 Flameshot 和 Dunst),但它无法杀死我的电池脚本。这是我在.xinitrc
文件中运行的自动启动脚本。
# My .xinitrc file
# This file will run as autostart
dunst &
flameshot &
setxkbmap -option caps:escape &
sxhkd -c ~/suckless/dwm/sxhkdrc &
~/.fehbg &
~/scripts/battery-notification &
xrdb ~/.Xresources &
exec dwm
我通过 xorg 的 startx 运行这个文件。如果我执行 a ps -ef | grep battery-notification
,它会显示超过 2 个实例(其中包括电池脚本和 grep)。
感谢您的回答:)
答案1
您可以在脚本中添加锁定文件机制。只需确保脚本退出时锁定文件被可靠地删除,例如通过设置陷阱:
#!/bin/bash
lockfile="/var/run/lock/batterystatus.lock"
if [[ -e "$lockfile" ]]; then exit 0; fi
trap 'rm -f "$lockfile"' EXIT
touch "$lockfile"
# ... your actual script code here
请注意,如果脚本以 终止SIGKILL
,则trap
不足以可靠地删除锁定文件。
经过 Kamil Maciorowski 的有益澄清后,这里是一个使用flock
.
#!/bin/bash
lockfile="/var/run/lock/batterystatus.lock"
exec 100>"$lockfile"
if ! flock -n 100; then exit 0; fi
# ... your actual script here
如果需要,这将创建锁定文件,并重定向文件描述符100
(选择几乎任意)(1)到锁文件。然后它尝试通过 来锁定该文件描述符flock
。如果成功,锁定将一直保持到脚本退出为止。另一方面,如果另一个脚本实例已经锁定了该文件描述符,则该脚本将立即退出。
请注意,无需清理锁定文件 - 所执行的锁定flock
与此处相关。这也意味着存在锁定文件的存在并不意味着脚本不应该启动——只有该文件上存在锁定才意味着不应该启动脚本。
这个想法取自这里。如需进一步阅读,请查看
- bash集群:如果无法获取锁则退出(在这里您可以看到,您甚至可以使用脚本文件本身作为锁定文件 - 如前所述,只有锁定才起作用,而不是文件的存在/不存在)。
(1)如果你有 Bash > 4.1,你可以有 shell自动分配通过 -Syntax 的空闲文件描述符,如下所示:{variable-name}>redirection-target
exec {lockfd}>"$lockfile"
if ! flock -n "$lockfd"; then exit 0; fi
shell 将查找下一个空闲文件描述符(限制为仅使用描述符编号 > 9),并将实际使用的描述符存储在变量中$lockfd
以供进一步使用。
答案2
我还没有尝试过,但这可能有效:
在 .xinitrc 脚本的顶部:
trap 'kill 0' EXIT
这将杀死进程组中的所有进程。您可能不想在最后执行 dwm。只需给它 dwm 而无需执行;这将使父 bash shell 保持打开状态,直到 dwm 终止。
答案3
You can add below commands to kill the battery script while logging in
ps -eaf | awk 'BEGIN{IGNORECASE=1}/battery/ && !/awk/{print "kill -9 "$2}'| sh