0

I created an .sh file for my remote laptop that would play an alarm file through ffplay and send me a telegram message whenever the power plug got disconnected. The file worked great when I ran it in a terminal so I though I'll just create a service for it.

Followed a tutorial to make it work but found out that the audio file was no longer playing when using it as a service so I decided to delete the service for which I followed this tutorial.

When I check the service by using $ systemctl status battery_alarm.service the file can no longer be found so I figured it was all done but even after restarting the laptop, update & upgrade, it is still running somewhere.

It's not a big deal since I still get my Telegram message but I would like to solve this mystery and find out where and what I need to delete to have this stop. Any advice for this noob? :-)

edit: The .sh file used for the service was:

#! /bin/bash
echo "monitoring"
power=$(cat /sys/class/power_supply/BAT0/status)
# Set the API token and chat ID
API_TOKEN="<removed for obvious reasons :-)>"
CHAT_ID="1234567890"

# Set the message text
MESSAGE="HP Victus Unplugged"


while true; do
  actual=$(cat /sys/class/power_supply/BAT0/status)
  # echo $actual
  if [ $actual != $power ]; then
     power=$actual
     echo $actual
  fi
  if [ $actual == "Discharging" ]; then
     echo "discharging"
     # Use the curl command to send the message
     curl -s -X POST https://api.telegram.org/bot$API_TOKEN/sendMessage -d chat_id=$CHAT_ID -d text="$MESSAGE"
     amixer -D pulse sset Master 100%
     ffplay -autoexit -nodisp critical.mp3
  fi

  sleep 10
done

Link to the audio file for those who would like to have a copy

edit: After I changed the message in the checkpower.sh file, I now get 2 different messages. The new message in the modified checkpower.sh containing the state and battery percentage and the old message I used to have. So it seems like when I created the service, a copy of the checkpower.sh file was created which still runs somewhere. One message informing me is enough for me. Any idea how to find this unwanted service and kill it?

edit: I tried the forkit way which gave me the pids for the exec lines

15:52:07 exec   112099                 cat /sys/class/power_supply/BAT0/status
15:52:07 exec   112100                 curl -s -X POST https://api.telegram.org/bot
15:52:07 exec   112102                 amixer -D pulse sset Master 100%
15:52:07 exec   112104                 ffplay -autoexit -nodisp critical.mp3
15:52:07 exec   112108                 sleep 10

The output I got when trying these pids was:

(base) qwerty@qwerty-Victus:~$ systemctl status 112099
Failed to get unit for PID 112099: PID 112099 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status 112100
Failed to get unit for PID 112100: PID 112100 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status 112102
Failed to get unit for PID 112102: PID 112102 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status 112104
Failed to get unit for PID 112104: PID 112104 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status 112108
Failed to get unit for PID 112108: PID 112108 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status --user 112099
Failed to get unit for PID 112099: PID 112099 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status --user 112100
Failed to get unit for PID 112100: PID 112100 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status --user 112102
Failed to get unit for PID 112102: PID 112102 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status --user 112104
Failed to get unit for PID 112104: PID 112104 does not belong to any loaded unit.
(base) qwerty@qwerty-Victus:~$ systemctl status --user 112108
Failed to get unit for PID 112108: PID 112108 does not belong to any loaded unit.

qwerty
  • 11
  • 2

1 Answers1

0

Any idea how to find this unwanted service and kill it?

Several:

  1. Your mainloop is centered around sleep, so run pgrep sleep and use the found PID to check which service it might be running in – use systemctl status [--user] <pid> (both with the --user option and without, whichever returns a more accurate result).

    Alternatively, run systemd-cgls or systemctl status (without a service name) and look through all cgroups one by one, searching for any cgroup that has both bash and sleep processes.

    Either of those methods will let you track down the process either to a system service, or to a user-level service (managed through systemctl --user), or to a cron job, or something similar.

  2. Your script calls external executables, so use forkstat or bpftrace's execsnoop.bt to determine which process is the one that launches curl or amixer. (Run forkstat as root, then unplug power supply and wait for the script to trigger the notification, look for an 'exec' line mentioning 'curl'; your script's PID will be in the 'fork ... parent' event two lines above.)

    Once you know the PID, see instructions in #1 above.

Suggestion for a better script: Instead of checking every 10 seconds, have the script be event-triggered. The acpid daemon already exists for this purpose – it will run specified scripts on specified ACPI events, which includes battery plug/unplug.

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • Thanks for reply and for advising me on the ACPI. I like the forkstat way and looked for the pid on the exec rows. I tried both ways but it only tells me that the pid does not belong to any loaded unit. – qwerty Mar 05 '23 at 20:13
  • Those are not the PIDs you need to check – you need to find their *parent* PID, which is 2-3 lines above every "exec" row. The child processes will have already exited by the time you run systemctl so there's no use in searching for them. – u1686_grawity Mar 05 '23 at 20:29
  • Awesome! Yes, that did the trick. I found the running service Loaded: loaded (/lib/systemd/system/powerFailureAlarm.service; enabled; vendor preset: enabled) I followed the tutorial and was able to delete the service. Thanks for your help (I was unable to vote, new account) – qwerty Mar 06 '23 at 05:23