Unable to execute a python3 script from rc.local - python

The Python script is unable to work in rc.local, as soon as it nevet gets executed. My idea is to run the script when the Raspberry Pi gets boot.
I have tested it with this sentence. The log.txt file only appears when I execute the program manually.
f = open("log.txt", "w")
f.write("log is working")
f.close()
Before that, I have tried to insert a time.sleep(30), to use usr/bin/python3, to change the head of the script to #!/usr/bin/env python3, change the user is executing the program to -u pi and a lot of things I can't even remember.
The final sentence is had before exit(0) is
sudo /usr/bin/python3 /home/pi/script.py &
rc.local is working as soon as it runs an echo that I have create in the file.

Finally the problem I had was that the script needed network, so I added it to crontab -e.
It still didn't work so I changed the raspi-config, as there is an option for network wait to network, but without success.
Finally, as that solution didn't work too, I added an sleep in the command as follows to wait for network:
#reboot sleep 40 && /usr/bin/python3 /home/pi/script.py
That finally worked.

Related

Problem running python script at boot raspberry pi

I'm having an insane amount of trouble with my script at startup, I've tried countless ways and spent hours trying to get this to work.
I have a python script that I need to run at startup. However, it needs access to the internet, so I have to wait for the network.
I have tried many ways in the several tutorials I have tried, with crontab, by making a service with systemd, with rc.local however none of these have worked.
The only way that I was able to work was by doing a .desktop Desktop Entry, but that only worked for me while I had an external monitor plugged in, and my raspberry pi will be running without one.
Also, I was able to make my script run using the service method and now the rc.local
by adding this line:
sudo bash -c '/usr/bin/python3 /home/pi/Projects/capstone/main.py > /home/pi/capstone.log 2>&1' &
However, in the python script that I am trying to run, I have the following code:
os.system("sudo killall servod")
time.sleep(1)
os.system('sudo ~/PiBits/ServoBlaster/user/./servod')
And for some reason, it's not running my script correctly because I get the following error in my logs:
servod: no process found
sudo: /root/PiBits/ServoBlaster/user/./servod: command not found
The first one is expected because I run sudo killall servod when it may or may not be started, but the second one "Command not found" is what is the issue, if that bit of code doesn't get executed my program doesn't work.
Anyone out there could help me out with this?
Replace:
os.system('sudo ~/PiBits/ServoBlaster/user/./servod')
with:
os.system('sudo /home/pi/PiBits/ServoBlaster/user/./servod')
Double check the path and try to use absolute path
Make sure you script has permission 644
You can also try to copy the script to /etc/init.d and run it as init.d script. You do need to add the following to your script:
### BEGIN INIT INFO
# Provides: scriptname
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
sudo chmod +x <yourscript.py>
sudo update-rc.d <yourscript.py> defaults
One way you could easily wait for the network inside your python script is to ping a server until successful -- in this case Google.
def wait_for_network():
while os.system("ping -c 1 8.8.8.8") != 0:
time.sleep(1)
return
As for running the script at startup, I recommend editing /etc/xdg/lxsession/LXDE-pi/autostart and adding your python script in there with the format
#python3 home/pi/your_script.py

cron invokes bash script which invokes "script" to run python program. Next line of bash script runs immediately, before script/python completes

When I run the following bash script via cron, the last line runs before the prior line has completed. Why? And how can I enforce the order I want?
I'm convinced that cron is the culprit here somehow, but for the sake of argument, here's a dummy bash script (Obviously, this is just an illustration. In the real world I'm doing some work in the python program and then trying to copy its work product to another place after it's done.):
#!/usr/bin/env bash
cd /tmp/kier/script
script output -c "./sleeper.py; echo '...and we are done'"
echo "This is the next line after invoking script..."
...and for completeness, here's the python script, sleeper.py:
#!/usr/bin/env python3
import time
print("python program starting")
time.sleep(5)
print("python program done")
When I run the bash script from the command line all is well. Specifically, the "This is the next line..." text prints at the very end, after the 5-second sleep.
But when I run it from cron, the output comes in the wrong order (this is the email that comes to me after cron runs the job):
Script started, file is output
Script done, file is output
This is the next line after invoking script...
python program starting
python program done
...and we are done
Script started, file is output
So you can see that "This is the next line..." prints before the python script has even really started. As though it's running the python script in background or something.
I'm stumped. Why is this happening and how can I make the echo command wait until script has finished running the python program?
(Finally, Yes, I could include my extra command inside the commands I send to script, and I am actually considering that. But come on! This is nuts!)
I should follow up and share the solution I came up with. In the end I never got a good answer to WHY it is behaving this way in my (RedHat) environment, so I settled on a workaround. I...
created a sentinel file before invoking "script",
included an extra command deleting the sentinel file in the script's command text, and then
waited for the sentinel file to go away before continuing.
Like this:
sentinel=`mktemp`
script output -c "./sleeper.py; rm $sentinel"
while [ -f $sentinel ]
do
sleep 3
done
Yes, it's a hack, but I needed to move on.

Auto run commands on Raspberry pi

i wanted to know what would be the best approach to solving this issue. I would like to run a bunch of commands to run some python scripts and a service when the raspberry pi loads into the desktop. Here are my commands:
cd /var/www/html/
python servocontrol.py
cd /var/www/html/Misc
python temp1.py
python seven_segment.py
sudo /etc/init.d/livestream.sh start
My initial method which i read on most post was to add it in the rc.local by:
sudo nano /etc/rc.local
And paste the exact commands in it as follows:
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
sleep 15
cd /var/www/html/
python servocontrol.py
cd /var/www/html/Misc
python temp1.py
python seven_segment.py
sudo /etc/init.d/livestream.sh start
exit 0
Sadly it didn't work. Kindly if any one can point out what i am missing or if there are additional steps that need to be done for this to work. If there are other methods i am also open to them!
Thanks
you can use crontab on raspberry pi (The crontab (short for "cron table") is a list of commands that are scheduled to run at regular time intervals on your computer system. The crontab command opens the crontab for editing, and lets you add, remove, or modify scheduled tasks.)
AND you can create service for your script.
it's very easy just need 5 sec search to find instruction.
are you want execute a script in server start?
you can use #reboot in cron

Stop raspbian/debian from within python

When I am away from my mountain, I monitor my Photo-voltaic system with Raspberry Pi and a small python script to read data and send it to my web page every hour. That is launched by a electo-mechanical switch that lights up the stuff for 15 minutes. But during that period, the script may run twice, which I would like to prevent as the result is messy (lsdx.eu/GPV_ZSDX).
I want to add some line at the end of the script to stop it once it has run once and possibly stop raspbian as well for a clean exit before the power is off.
- "exit" only exits a loop but the script is still running
- of course Ctrl+C won't do as I am away;
Could not find any tip in these highly technical messages in StackOverflow or in Rasbian help either.
Any tip?
Thanks
The exit() command should exit the program (break is the statement that will exit a loop). What behavior are you seeing?
To shut down , try :
python3:
from subprocess import run
run('poweroff', shell=True)
python2:
from subprocess import call
call('poweroff')
Note: poweroff may be called shutdown on your system and might require additional command line switches to force a shutdown (if needed).
For your case, structure the python script as a function using the following construct:
def read_data():
data_reading_voodo
return message_to_be_sent
def send_message(msg):
perform_message_sending_voodo
log_message_sending_voodoo_success_or_failure
return None
if __name__ == "__main__":
msg = read_data()
send_message(msg)
Structured like this, the python script should exit after running.
Next create a shell sript like follows (assuming bash and python, but modify according to your usage)
#!/bin/bash
python -m /path/to/your/voodo/script && sudo shutdown -h 6
The sudo shudown -h 6 shuts down the raspberrypi 6 minutes after the script is run. This option helps so you have some time after startup to remove the sript if you ever want to stop the run-restart cycle.
Make the shell script executable: chmod 755 run_py_script_then_set_shutdown see man chmod for details
Now create a cronjob to run run_py_script_then_set_shutdown on startup.
crontab -e Then add the following line to your crontab
#reboot /path/to/your/shell/script
Save, reboot the pi, and you're done.
Every time the rpi starts up, the python script should run and exit. Then the rpi will shutdown 6 minutes after the python script exits.
You can (should) adjust the 6 minutes for your purposes.
Thanks for all these answers that help me learn Pyth and Deb.
I finally opted for a very simple solution at the end of the script:
import os
os.system('sudo shutdown now')
But I keep in mind these other solutions
Thanks again,
Lionel

I run a program in a shell script. How do i know if it has loaded? (Linux)

I wrote a shell script that runs a python program. Then I want to load a file into the program using xdotool. Right now this is my code:
#!/bin/bash
cd ~/Folder
python program.py &
sleep 10
WID=$(xdotool search --onlyvisible program)
....
I really don't like my solution of just waiting 10 seconds so that the program is loaded. Is there a better way?
This really depends. If program.py is supposed to finish then go on to xdotool then you might want to use && instead of &. A single & means you want the command to execute then move on to the next command as soon as possible without waiting for it to finish. A dobule && means you want to wait for the execution to be done, then only continue if you have a zero error exit. You could also just remove the & or use ; if you want to run the next command regardless of program.py's success. Here's what I'm getting at:
#!/bin/bash
cd ~/Folder
python program.py &&
WID=$(xdotool search --onlyvisible program)
...
If program.py is supposed continue run while you run the xdotool command, but you need program.py to come to some ready state before you continue, then you're right in using &, but you need to monitor the program.py somehow, and get a signal from it that it is ok to continue. An ancient way of doing this is to simply let program.py create/touch/edit a file, and when that file is detected you continue. A more advanced way would be to use network sockets or similar, but I'd advice against it if you really don't need to do anything fancy. Anyway, if you make program.py create a signal file, say /tmp/.program_signalfile, when things are ready all you have to do is:
#!/bin/bash
cd ~/Folder
python program.py &
until [ -f /tmp/.program_signal_file ]
do
sleep 1
done
WID=$(xdotool search --onlyvisible program)
rm /tmp/.program_signal_file
...
In this last solution program.py and xdotool are both running at the same time. If that's what you were looking for.

Categories

Resources