0

I made Bash script what running fan for cooling. PIN20 is PWM out and this script work perfect. I run this script over therminal arroun 15 hours.

Afer all tests i register script for autoload after reboot like this:

$ sudo cp rpipwm.sh /etc/init.d/rpipwm.sh
$ sudo chmod +x /etc/init.d/rpipwm.sh
$ sudo update-rc.d /etc/init.d/rpipwm.sh defaults

After last line I get this error: update-rc.d: error: initscript does not exist: /etc/init.d//etc/init.d/rpipwm.sh

After that error I update with this:

$ sudo update-rc.d rpipwm.sh defaults

And reboot.

After reboot my script start to work and all is fine arround 20min. After that time my script stop to work. If I run this manualy on terminal script can work hours and hours with no errors.

What's mistake?

Here is my script.

#!/bin/bash
### BEGIN INIT INFO
# Provides:          rpipwm
# Required-Start:    $local_fs 
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: rpipwm
### END INIT INFO

FLAG="/var/log/rpipwm.log" if [ ! -f $FLAG ] ; then

    a="echo 20 > /sys/class/gpio/unexport;"
    a=$a"echo 20 > /sys/class/gpio/export;"
    a=$a"echo out > /sys/class/gpio/gpio20/direction" || true
    eval $a
    #start loop script
    i="0"
    temp="0"

    while true;
    do
        i=$(($i+1))
        #Read temp
        if [[ $(bc <<< "$i > 10") == 1 ]] ;
        then
            cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp)
            cpuTemp1=$(($cpuTemp0/1000))
        ##  cpuTemp2=$(($cpuTemp0/100))
            temp=$cpuTemp1
            i="0"
        fi
        a=""
        #If temperature is equal or lower than 39.99, the fan will stop spinning
        if [[ $(bc <<< "$temp < 39") == 1 ]] ;
        then
            a=$a"echo 0 > /sys/class/gpio/gpio20/value"
        fi
        #If temperature is between 40 and 42.99, the fan will start with 1 second burst and 1 second sleep
        if [[ $(bc <<< "$temp >= 40 && $temp <= 44") == 1 ]] ;
        then
            a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 0.5; echo 0 > /sys/class/gpio/gpio20/value; sleep 0.1 "
        fi
        #If temperature is between 43 and 47.99, the fan will start with 1 second burst and 0.5 second sleep
        if [[ $(bc <<< "$temp >= 45 && $temp <= 49") == 1 ]] ;
        then
            a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 1; echo 0 > /sys/class/gpio/gpio20/value; sleep 0.5" 
        fi
        #If temperature is equal or higher than 48, the fan will start spinning constantly
        if [[ $(bc <<< "$temp > 50") == 1 ]] ;
        then
            a=$a"echo 1 > /sys/class/gpio/gpio20/value" 
        fi

        eval $a
        sleep 0.1
    done

touch $FLAG

fi


UPDATE


I reorder script, put log in script and now have all to work properly and with no unexpected stop or break.

#!/bin/bash
### BEGIN INIT INFO
# Provides:          rpipwm
# Required-Start:    $local_fs 
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: rpipwm
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/wc3/palert
FLAG="/var/log/rpipwm.log"
(
    if [ ! -f $FLAG ] ;
    then
        a="echo 20 > /sys/class/gpio/unexport;"
        a=$a"echo 20 > /sys/class/gpio/export;"
        a=$a"echo out > /sys/class/gpio/gpio20/direction" || true
        eval $a
        #start loop script
        i="0"
        temp="100"

        while true;
        do
            i=$(($i+1))
            #Read temp
            if [[ $(bc <<< "$i > 5") == 1 ]] ;
            then
                cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp)
                cpuTemp1=$(($cpuTemp0/1000))
            ##  cpuTemp2=$(($cpuTemp0/100))
                temp=$cpuTemp1
                i="0"
            fi
            a=""
            #If temperature is equal or lower than 39.99, the fan will stop spinning
            if [[ $(bc <<< "$temp <= 39") == 1 ]] ;
            then
                a=$a"echo 0 > /sys/class/gpio/gpio20/value"
            fi
            #If temperature is between 40 and 42.99, the fan will start with 1 second burst and 1 second sleep
            if [[ $(bc <<< "$temp >= 40 && $temp <= 44") == 1 ]] ;
            then
                a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 0.5; echo 0 > /sys/class/gpio/gpio20/value; sleep 0.1 "
            fi
            #If temperature is between 43 and 47.99, the fan will start with 1 second burst and 0.5 second sleep
            if [[ $(bc <<< "$temp >= 45 && $temp <= 47") == 1 ]] ;
            then
                a=$a"echo 1 > /sys/class/gpio/gpio20/value; sleep 1; echo 0 > /sys/class/gpio/gpio20/value; sleep 0.5" 
            fi
            #If temperature is equal or higher than 48, the fan will start spinning constantly
            if [[ $(bc <<< "$temp >= 48") == 1 ]] ;
            then
                a=$a"echo 1 > /sys/class/gpio/gpio20/value" 
            fi

            eval $a
            sleep 0.1
        done

    touch $FLAG
fi

) &> /home/pi/rpipwm.txt

  • http://raspberrypi.stackexchange.com/q/40493/5538 – goldilocks Jul 19 '16 at 09:07
  • I not understand this. – Ivijan Stefan Stipić Jul 19 '16 at 09:09
  • 1
    It will be hard to debug your problem then. My point is as with any kind of persistent process if you do not arrange some kind of logging then it is difficult to say what it was doing at point A, B, C, and so on. Logging is not hard to arrange. It is certainly much easier than not doing it if you need to hypothesize about a problem which occurred, e.g., at point C. – goldilocks Jul 19 '16 at 09:22
  • Yeah you are right. I will read again and made debug of script. Interesting things is that on mynual run all work perfect. – Ivijan Stefan Stipić Jul 19 '16 at 09:51
  • Yes, as that generic question says, "I know the event is occurring and the script is executing, but it does not do what I intend. Strangely, it does when I run it manually, so I am very confused." This is not an uncommon problem. Note that processes started by init should background themselves and your script does not appear to do that. – goldilocks Jul 19 '16 at 09:56
  • I just update my script to see what error will catch. I'm confused because script work perfect but on auto execute stop working in 20min – Ivijan Stefan Stipić Jul 19 '16 at 10:00
  • I think what's happening is that you didn't actually write an init script to control this, you just put the script in init.d. The scripts in the init.d directory are used to start/stop/etc. some other daemon and then they exit. If they do not finish soon enough (I'd guess the value of "soon" on you system is 20 minutes), then init decides they are malfunctioning and kills them. I think you need to read up more on how init scripts are supposed to work. – MAP Jul 21 '16 at 08:34
  • Yes maby. I put @goldilocks's instructions and now my script working properly and clean. I don't have any issue for now. – Ivijan Stefan Stipić Jul 21 '16 at 08:39
  • Why did you decide to assign commands to $a and use eval $a rather than execute the commands directly? And why don't you compare with -gt and -lt – Dmitry Grigoryev Nov 10 '16 at 15:55

2 Answers2

1

This isn't an answer to the original question (as I understand, the problem disappeared on its own anyway), but rather a recommendation on your scripting.

I believe the big part of your problem is the eval statement. I don't see why you need it, and it certainly makes your code harder to debug. Also comparison operations could be made simpler using -gt and -lt operators.

Something like

        if [ $temp -lt 39 ] # temperature below 39
        then
            echo 0 > /sys/class/gpio/gpio20/value
        elif [ $temp -lt 44 ] # temperature above 39 but below 44
        then
            echo 1 > /sys/class/gpio/gpio20/value
            sleep 0.5
            echo 0 > /sys/class/gpio/gpio20/value
            sleep 0.1
        elif ... # next interval
            ... etc ...
        fi

With this code, you know for sure that (1) only one alternative can be executed at a time, and (2) the exact commands for each case. With eval $a, you can't be sure of anything unless you analyse all possible combinations of commands which modify $a.

Dmitry Grigoryev
  • 27,928
  • 6
  • 53
  • 144
0

Enable auto start at boot:

sudo cp rpipwm.sh /etc/init.d/rpipwm.sh sudo chmod +x /etc/init.d/rpipwm.sh sudo update-rc.d /etc/init.d/rpipwm.sh defaults not work

john
  • 1