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: 40833
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
Any language using left-hand whitespace for syntax is ridiculous

Any DMs sent on Twitter will be answered next month.
Fake doctors - are all on my foes list.

Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

User avatar
jojopi
Posts: 3424
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: 40833
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.
Any language using left-hand whitespace for syntax is ridiculous

Any DMs sent on Twitter will be answered next month.
Fake doctors - are all on my foes list.

Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

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”