Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

[Bash] {Solved} Script to auto shutdown/wake no longer works after move from Ubuntu.

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
heyho
Posts: 3
Joined: 2024-04-01 18:35

[Bash] [Solved] Script to auto shutdown/wake no longer works after move from Ubuntu.

#1 Post by heyho »

For some background, I've recently moved from Ubuntu server to Debian, something I've wanted to do for some time.

The server is purely for home use, and runs Jellyfin, TVheadend and Samba. Running Debian 12 on the same hardware (TS150 Lenovo)

On my previous install of Ubuntu server, I was running the following script (not written by me), which monitors for activity on various user defined ports, and shuts down after a pre-determined time idle, at which point it also writes to the time to wake for the next scheduled recording to the bios.

Code: Select all

#!/bin/bash

# BASIC SETTINGS change at wish

# Settings you have to look at
# TvHeadend login and password
tvh_login=YOUR_LOGIN_NAME
tvh_password=YOUR_PASSWORD
# (post recording) process activity to be checked, leave blank to deactivate
process_check=(PROCESS_A PROCESS_B)

# Settings you might look at
# portnumbers to be checked for user activity (tvheadend 9981 + 9982 and samba 445)
port_numbers=(9981 9982 445)
# minimum time in seconds needed for consecutive shutdown AND startup
safe_margin_shutdown=600
# minimum time in seconds needed to start up the computer properly
safe_margin_startup=180
# minimum time in minutes not to shutdown after last user activity (watching tv/recording, up-/downloading files, booting the system)
idle_time_shutdown=30
# maximum time in hours not to wake up for updating EPG
epg_hours=48
# interval in seconds the script will check if the system should be shutdown
script_int=60

# END OF BASIC SETTINGS keep out from here ;-)

# retrieve IP_address tvheadend server
tvh_ip=$(hostname -I | awk '{print $1}')

# set language
export LANG=C

# set session start
uptime_boot_sec=$(cat /proc/uptime | awk -F ' ' '{print$1}' | awk -F '.' '{print$1}')
boot_time=$(($(date +%s)-uptime_boot_sec))

# initial value do not change
recording=1

# check for shutdown
until [ $recording -eq 0 ];do

# initial values do not change
    recording=0
    shutdown_timer=$idle_time_shutdown
    ping_array=()

# countdown to shutdown
    until [ $shutdown_timer -eq 0 ];do
        shutdown_timer=$((shutdown_timer-1))

# check for server connection tvheadend samba or any other server according to settings above
        status_netstat=1
        until [ $status_netstat -eq 0 ];do
            status_netstat=0
            sleep $script_int
            for i in $( echo "${port_numbers[*]}"); do
                port_no=$i
                for i in $(echo $(netstat -n | grep -i "ESTABLISHED" | grep "$tvh_ip:$port_no" |  awk -F ':' '{print ":"$2}' | sed 's/:'$port_no'\|[ ]//g')); do
                    shutdown_timer=$idle_time_shutdown
                    status_netstat=1
                    ping_array[$(echo "${#ping_array[*]}")]=$i
                done
            done
            ping_array=($(echo "${ping_array[*]}" | sed 's/[ ]/\n/g' | awk '!a[$0]++' ))
        done
        for i in $(echo "${ping_array[*]}"); do
            if [ $( ping -c1 $i | grep "received" | awk -F ',' '{print $2}' | awk '{print $1}' ) -eq 0 ]; then
                ping_array=($(echo "${ping_array[*]/$i/}"))
            fi
        done
        if [ $(echo "${#ping_array[*]}") -eq 0 -a $boot_time -lt $(($(date +%s)-idle_time_shutdown*60)) ]; then
            shutdown_timer=0
        fi
        if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -ne 0 -a $shutdown_timer -eq 0 ]; then
            shutdown_timer=1
        fi

    done

# check for active post recording processes
    total_processes=0
    for i in $( echo "${process_check[*]}"); do
        counter=$( ps -A | grep "$i" | wc -l )
        total_processes=$((total_processes+counter))
    done
    if [ $total_processes -ne 0 ]; then
        recording=$((recording+1))
    fi

# check for active users
    if [ $(who | wc -l) -ne 0 ]; then
        recording=$((recording+1))
    fi

# retrieve and calculate wake up data
    if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -eq 0 ]; then
        wake_after_min=$((epg_hours*60))
        if [ $(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}' | wc -l) -gt 0 ]; then
            wake_after_min_temp=$(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
            if [ $wake_after_min -gt $wake_after_min_temp ]; then
                wake_after_min=$wake_after_min_temp
            fi
        fi
    else
        wake_after_min=0
    fi
    wake_after_secs=$((wake_after_min*60))

# check safe margin shutdown
    if [ $safe_margin_shutdown -gt $wake_after_secs ]; then
        recording=$((recording+1))
    fi

done

# set RTC wake up time
stop_date=$(date +%s)
wake_date=$((stop_date+wake_after_secs-safe_margin_startup))
echo 0 > /sys/class/rtc/rtc0/wakealarm
echo $wake_date > /sys/class/rtc/rtc0/wakealarm

# shutdown computer
sudo shutdown -h now
I've used Webmin to setup the script as a systemd service to run from boot. I can confirm it's running, but it doesn't seem to work anymore. The output from "systemctl status wake.service" returns the following:

Code: Select all

Loaded: loaded (/lib/systemd/system/wake.service; enabled; preset: enabled)
     Active: active (running) since Mon 2024-04-01 19:32:50 BST; 8min ago
   Main PID: 443 (wake.sh)
      Tasks: 2 (limit: 9345)
     Memory: 4.1M
        CPU: 452ms
     CGroup: /system.slice/wake.service
             ├─ 443 /bin/bash /usr/local/bin/wake.sh
             └─1698 sleep 60

Apr 01 19:32:50 debian systemd[1]: Started wake.service - Auto shutdown and wake.
Apr 01 19:34:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:35:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:36:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:37:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:38:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:39:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
Apr 01 19:40:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
The script is quite old, but definitely worked on the most recent version of Ubuntu sever LTS. I'm not asking for somebody to just fix this for me, but maybe explain what the differences might be between Ubuntu and Debian in terms of the way the script is executed. I've got a bit of programming experience, but not with bash, and not for some time now.
Last edited by heyho on 2024-04-04 09:11, edited 2 times in total.

User avatar
fabien
Forum Helper
Forum Helper
Posts: 671
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 61 times
Been thanked: 154 times

Re: [Bash] Script to auto shutdown/wake no longer works after move from Ubuntu.

#2 Post by fabien »

Hello, welcome to the forums!
heyho wrote: 2024-04-01 19:03

Code: Select all

Apr 01 19:40:51 debian wake.sh[443]: /usr/local/bin/wake.sh: line 76: [: too many arguments
line 76 is

Code: Select all

if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -ne 0 -a $shutdown_timer -eq 0 ]; then
A simplified code that satisfies both conditions is

Code: Select all

if [ 1 -ne 0 -a 0 -eq 0 ]; then echo "shutdown_timer set to 1"; fi
The second condition cannot raise an error because shutdown_timer is initialized as an integer before in the code. Therefore, the reason comes from something in the first condition that may prevent this expression from generating an integer.
You can simulate a similar error like this:

Code: Select all

$> shutdown_timer="0"
$> unset testvar
$> [ $testvar -ne 0 -a $shutdown_timer -eq 0 ]
bash: [: too many arguments
So you have to find what can trigger this error in this expression:

Code: Select all

curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'
  • Is curl installed?
  • Are tvh_login and tvh_password set correctly in the script?
  • Is your local server working properly? You can test if it works:

Code: Select all

$> curl -s --user YOURtvh_login:YOURtvh_password http://127.0.0.1:9981/status.xml
  • If it works, does this output a single line:

Code: Select all

$> curl -s --user YOURtvh_login:YOURtvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions"
  • And finally, does this output a single number:

Code: Select all

curl -s --user YOURtvh_login:YOURtvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'
The script you are using was not designed to account for possible errors.

heyho
Posts: 3
Joined: 2024-04-01 18:35

Re: [Bash] Script to auto shutdown/wake no longer works after move from Ubuntu.

#3 Post by heyho »

Thank you for the welcome, and for taking the time to look at my problem. I can't pretend I understand 100% of your explanation, but I'm getting there I think.
Is curl installed?
Yes, latest version.
Are tvh_login and tvh_password set correctly in the script?
I think so... however...
Is your local server working properly? You can test if it works:
This returns 401 Unathorised.

Code: Select all

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>401 Unauthorized</TITLE>
</HEAD><BODY>
<H1>401 Unauthorized</H1>
<P STYLE="text-align: center; margin: 2em"><A HREF="/" STYLE="border: 1px solid; border-radius: 4px; padding: .6em">Default login</A></P><P STYLE="text-align: center; margin: 2em"><A HREF="/login" STYLE="border: 1px solid; border-radius: 4px; padding: .6em">New login</A></P></BODY></HTML>
However from the browser on a local machine I can access status.xml without a problem, using the same username and password. TVheadend is otherwise functioning correctly. I'm sure (I hope) that this is going to turn out to be something stupid. The username and password for the normal user are tvh and tvh - and these are just typed into the script in plain text where the place holders are. There is also an "admin" user in this version, but I've tried that too and it displays the same behaviour.

heyho
Posts: 3
Joined: 2024-04-01 18:35

Re: [Bash] Script to auto shutdown/wake no longer works after move from Ubuntu.

#4 Post by heyho »

Ok, after much headscatching, I found a setting in the web interface for HTTP authentication. I've changed it from "Digest" to "Plain(insecure)", and now the curl command returns the expected result.

User avatar
fabien
Forum Helper
Forum Helper
Posts: 671
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 61 times
Been thanked: 154 times

Re: [Bash] Script to auto shutdown/wake no longer works after move from Ubuntu.

#5 Post by fabien »

heyho wrote: 2024-04-02 20:40 Ok, after much headscatching, I found a setting in the web interface for HTTP authentication. I've changed it from "Digest" to "Plain(insecure)", and now the curl command returns the expected result.
Glad to know you found a solution. I assume this was also configured this way in your previous system.
Please mark you topic as [Solved] by editing the title of your first post, e.g.
[Bash] [Solved] Script to auto shutdown/wake no longer works after move from Ubuntu.

curl should let you use "Digest" authentication, even if you don't seem very concerned about giving away your password :)
man 1 curl wrote: --digest
(HTTP) Enables HTTP Digest authentication. This is an authentication scheme that prevents the password from being sent over the wire in clear text. Use this in combination
with the normal -u, --user option to set user name and password.
You can test it like this after returning to "Digest" in the web interface:

Code: Select all

$> curl -s --user YOURtvh_login:YOURtvh_password --digest http://127.0.0.1:9981/status.xml
If it works, just change this part in the script for each curl command.

Post Reply