Ctrl-c does not stop Python script on raspberry pi - python

I am trying out a python tutorial on the raspberry pi, and have found that more often than not, CTRL+C, or selecting shell > interrupt execution from the menu, will not stop a running script.
I do get a warning when I close the entire window: your program is still running, do you want to kill it?, but it looks like the script even runs when the window is closed, because the cursor changes into an hourglass for all python windows.
How can I force stop a python script on raspberry?

Try executing the command ps -ax | grep python in command line to find the process id of your script. Once you find that, kill that process using this command sudo kill <process_id>

Related

Start terminal on Raspberry Pi using SSH

My question regards SSH on Raspberry Pi.
I am able to successfully ssh on to the Pi using the command:
sudo ssh pi#<ipaddress>
and then entering the password.
Let's say I have a Python script file on the Pi that I execute over SSH. Let's say the script reads:
import time
while True:
print('Hello')
time.sleep(1)
This will print 'Hello' every second whilst the terminal/command prompt window is still open (that is, the computer I am using to access the Pi is running and the SSH session remains open). If I close the connection, then the code will stop being executed on the Pi.
Is there a way I can use SSH to keep the code running on the Pi even when I close the window running SSH on the computer I am using to access the Pi? As in the Pi will keep printing 'Hello' even after I shut down my computer. Maybe by entering a command to open a terminal window on the Pi itself and running the script in that terminal window?
Is there a way this can be done?
Thanks
There are two options I can think of:
create a cron job. This method is usually used to execute scripts/programs repeatedly. The job is triggered by the cron program, so it doesn't matter whether or not you are connected to the Pi, as long as it runs. You just have to connect once and setup the job (typically using crontab -e).
use screen (on Wikipedia) or tmux (on Wikipedia). Those are called terminal multiplexers, and allow you to keep shells (and thus any script/program) running although you aren't connected. Note that, in this case, you will have to manually start your script each time, so this solution is well-suited to scripts that run for a long time but are not started too often.

how to use systemd to run a python script forever and restart if it dies halfway on raspberry pi 3?

I have read that upstart is obsolete in favor of systemd for raspberry pi 3.
My question is how do I run a python script :
a) forever unless I manually kill it
b) can restart if it dies due to some exception or stop running automatically without any human intervention
my python script itself is already using modules like schedule and while True loops to keep running certain jobs every few seconds.
I am just worried that it will die/stop (which it did) after some indeterminate amount of time.
If it stops, all I want is for it to restart.
Currently, I run the script by double clicking it to open in Python IDLE (2.7) and then run module.
What is the best way to run and open a python script and let it run continuously non-stop and then have it auto restart when it dies / stops for whatever reason?
See this picture where it suddenly stops by itself at 5 plus am
I think you should take a look at Python Supervisor. Supervisor will manage the restart in the event of a crash or even machine re-starts.
http://supervisord.org/
An easier method might be the handle the failure within your script. If it is failing due to some exception, wrap the offending code in a try:except block and handle it gracefully within the script.
That said, this post has the information you need to use systemd to execute a BASH script:
https://unix.stackexchange.com/questions/47695/how-to-write-startup-script-for-systemd
Within your script, you can easily run a python script and catch its return value (when it returns failure in your case) and react appropriately.
Something like this:
#!/bin/bash
python ~/path/to/my/script/myScript.py
if [ $? -ne 0 ] ; then #handle the failure here.
If that won't work either, you can create a script whose sole job is to call the other script and handle its failures, and use systemd to call that script.

Run Script in Foreground On Boot Raspberry Pi

I've a script to run on boot and I'd like to use the keyboard to interact with the script. I've successful set this up to run in crontab; however, the script runs in the background and I can't use the keyboard to interact with the script. Here's a simplified example of the script:
def write_to_txt(item_to_write):
with open("my_txt_file.txt", "a") as myfile:
myfile.write('\n'+str(item_to_write))
while True:
keys_to_enter = raw_input()
write_to_txt(keys_to_enter)
Please could someone point me in the right direction?
I found out how to run the script on boot and allow the keyboard to interact with the program. To the ~/.bashrc file, I appended:
sudo python /home/pi/example.py
If I understand correctly you want your program to attach its stdin to tty1? I.e. the terminal which you see on screen if you have a display hooked up - this is where by default keyboard input would end up if X windows is not installed or the tty is not switched with Ctrl+Alt+Fx?
Is moving the ownership of the background script process to the shell on tty1 an option? If so, the easiest may be to auto-login the Pi (or the user will need to login with the keyboard on startup). Then auto-start the program on tty1 so its stdin/stdout is tied to tty1.
To achieve the latter, I think you can put its invocation into one of the bash startup scripts, something like what is suggested here: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=7192
You can run a script in foreground at boot by adding a line to /etc/rc.local
This works in my experience, in particular if the Raspberry pi is configured to wait for network to be available when booting

Unix: Have Python script constantly running best practice?

I have a Python script which process data off of a HTTP data stream and I need this script to in theory be running at all times and forever unless I kill it off manually to update it and run it again.
I was wondering what the best practice to do this was on a Unix (Ubuntu in particular) so that even if Terminal is closed etc the script continues to run in the background unless the process or server are shut down?
Thanks
From your question you are implying that you are going to start the script from your terminal and not by any of Linux's startup script management methods like systemd or upstart or init.d scripts.
If you intend to start your script from terminal, and you want it to continue to run after you close your terminal, you need to do two things
1. Make it run in the background by appending '&' after your script.
2. When you close the terminal, the shell associated to it sends HUP signal to all the processes before it dying. To ignore the HUP signal and continue to run in the background you need to start your script with 'nohup'.
tl;dr
Run your script this way:
$ nohup python mypythonscript.py &
Adding your script to rc.local would work, but 'best practice' in my opinion would be to use Upstart. See this post:
Daemon vs Upstart for python script
It's an infinite loop. You can launch the script at startup and it will run forever until you kill the process itself or shut the computer down.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
while True:
print 'Hello'
time.sleep(2) # 2 second delay
I am not sure how "best practice" this is but you could do:
Add the program to:
/etc/rc.d/rc.local
This will have the program run at startup.
If you add an '&' to the end of the line it will be run in the background.
If you dont want to run the program manually (not at startup) you could switch to another tty by pressing ctrl + alt + f1, (this opens tty1 and will work with f1 - f6) then run the command. This terminal you do not have to have open in a window so you dont have to worry about it getting closed. To return to the desktop use ctrl + alt + f7.

How do I write a python program to get my Linux machine to restart at a signal?

I have one main program "main.py" that may freeze occasionally. Whenever I detect this happens, I want to have a separate program "watch.py" get my Linux machine to restart. These scripts start at bootup automatically since I edited /etc/rc.local.
Right now /etc/rc.local looks like this -
python watch.py &
python main.py &
This should let both programs run simultaneously. When I notice main.py has frozen, I'll give a signal manually to watch.py (using a remote TCP connection) to restart. What should my python code or shell script be to actually restart the system when "watch.py" receives a signal?
Possible answers could be writing some python code to restart a Linux machine, writing some python code to exit with a certain argument, and upon noticing the argument, execute "sudo reboot".

Categories