Viper1953
Posts: 19
Joined: Tue Dec 31, 2013 10:09 am

rc.local only loading 1 script on boot

Fri Jan 31, 2014 2:47 pm

Hi Guys,

I have two scripts in my rc.local file that are virtually identical (but pin numbers different etc). Only one is loading on startup though.

Here is the one that DOES load:

Code: Select all

# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
 
# Define a function to keep script running
def loop():
    raw_input()
 
# Define a function to run when an interrupt is called
def shutdown(pin):
    call('halt', shell=False)
 
gpio.setmode(gpio.BOARD) # Set pin numbering to board numbering
gpio.setup(7, gpio.IN) # Set up pin 7 as an input
gpio.add_event_detect(7, gpio.RISING, callback=shutdown, bouncetime=200) # Set up an interrupt to look for button presses
 
loop() # Run the loop function to keep script running
and here is the one that DOES NOT load:

Code: Select all

import RPi.GPIO as GPIO

# Define a function to keep script running
def loop():
    raw_input()


# Define a function to run when an interrupt is called
def LEDON(pin):
	GPIO.output(25, True)
		         
GPIO.setmode(GPIO.BCM) #Set pin numbering to GPIO numbering
GPIO.setup(24, GPIO.IN) # Set up GPIO 24 as an input (button)
GPIO.setup(25, GPIO.OUT) # Set GPIO 25 as an output (LED)
GPIO.output(25, False)

GPIO.add_event_detect(24, GPIO.RISING, callback=LEDON, bouncetime=200)

loop() # Run the loop function to keep script running
And just to confirm, this is my rc.local entry:

Code: Select all

fi
python /home/pi/scripts/PiSupply/softshut.py
python /home/pi/scripts/button/button.py
exit 0
Softshut.py is the one that DOES load.

Any help greatly appreciated!!

User avatar
elParaguayo
Posts: 1943
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 3:22 pm

Just a guess: If softshut is running a loop then it will never exit, so I don't think the next line of your rc.local file will execute.

Have you tried adding a " &" at the end of the line to send the process to the background e.g.

Code: Select all

fi
python /home/pi/scripts/PiSupply/softshut.py &
python /home/pi/scripts/button/button.py &
exit 0
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.

Viper1953
Posts: 19
Joined: Tue Dec 31, 2013 10:09 am

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 5:40 pm

Yep, just tried that and unfortunately it didn't make a jot of difference!

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 5:43 pm

Stop using /etc/rc.local
Create two scripts in /etc/init.d to get those two long running server processes running (there's a skeleton script /etc/init.d/skeleton).
Use update-rc.d to make them active and run at boot time

It's normal practice to move the scripts being started that way to /usr/local/bin
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
jojopi
Posts: 3274
Joined: Tue Oct 11, 2011 8:38 pm

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 6:47 pm

You definitely need the background "&"s. Otherwise if the scripts do not exit, the rest of the boot sequence will be delayed indefinitely. (This is one reason that rc.local may be better than init.d/*, for beginners. It is always the very last script to run before starting console logins, so a mistake will not break SSH access.)

Both of the programs appear to use raw_input() as a blocking mechanism. That will not work when started at boot, because standard input is /dev/null, which returns an immediate end of file. Boot scripts are not supposed to expect keyboard interaction. Alternative methods of keeping the programs running, without wasting CPU time, include:

Code: Select all

def loop():
    import signal
    while True:
        signal.pause()

def loop():
    import time
    while True:
        time.sleep(60)

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 6:58 pm

If you set-up the headers in your /etc/init.d/ script you can ensure that it starts after networking and sshd are alive.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

Viper1953
Posts: 19
Joined: Tue Dec 31, 2013 10:09 am

Re: rc.local only loading 1 script on boot

Fri Jan 31, 2014 8:22 pm

DougieLawson wrote:If you set-up the headers in your /etc/init.d/ script you can ensure that it starts after networking and sshd are alive.
Thanks for the info Dougie, while it is much appreciated its a little too advanced for me at the moment. I did take a look at the skeleton script and it just confused me even more!
jojopi wrote:You definitely need the background "&"s. Otherwise if the scripts do not exit, the rest of the boot sequence will be delayed indefinitely. (This is one reason that rc.local may be better than init.d/*, for beginners. It is always the very last script to run before starting console logins, so a mistake will not break SSH access.)

Both of the programs appear to use raw_input() as a blocking mechanism. That will not work when started at boot, because standard input is /dev/null, which returns an immediate end of file. Boot scripts are not supposed to expect keyboard interaction. Alternative methods of keeping the programs running, without wasting CPU time, include:

Code: Select all

def loop():
    import signal
    while True:
        signal.pause()

def loop():
    import time
    while True:
        time.sleep(60)
This has worked brilliantly. I used the first option, combined with the "&"s and its now fully functioning.

Many thanks for your help and input.

Return to “Python”