I need to run Python scripts from SSH on my Raspberry Pi, while still being able to get input from a user on the Raspberry Pi via a USB keyboard emulator (card reader). I would normally be able to use raw_input for this, but if I run the Python script through SSH, it does not create a window and it will not be active so it will receive no input.
Is there any way to ensure a Python script will be active (the top window), even while using SSH to launch it? Or, is there another way to get user input without using raw_input, and works in the background (without an active window)?
Thanks in advance :)
PS: If I have to use other languages (like C) then invoke it in Python, this is fine, I will be able to do that.
I've solved it the best I can, with help from #Gaurav Dave
I now have a script which creates a new terminal window upon launch, using Popen from sys. The script looks like this...
from sys import executable
from subprocess import Popen, CREATE_NEW_CONSOLE
Popen([executable, 'window.py'], creationflags=CREATE_NEW_CONSOLE)
and window.py is simply a test script that prints some text and waits for a certain amount of time...
import time
print("Hello M8!")
time.sleep(5)
window.py will be the script that takes the input as that is the one that has the window.
Related
I want to open a PuTTY window, login to some server and enter few commands right after that and at the end save the output. I want to see the PuTTY window open and all activity that I am doing via program (hence need PuTTY GUI).
Here is what I have tried:
I am able to open a new window and login in it. But using stdin.write I am not able to enter further commands in the same window. What am I doing wrong here? I am very new to python. Please help.
import subprocess
from subprocess import Popen, PIPE, STDOUT
p = subprocess.Popen("putty.exe demo#Test.Rebex.Net -pw password", stdout=PIPE, stdin=PIPE, stderr=STDOUT)
p.stdin.write("ls".encode("utf-8"))
print(p.stdout.readlines())
I have tried Paramiko, and don't want to use it, as it fails to display/print the output of commands like top.
PuTTY is a GUI application, it does not use a standard input. It is not intended for automation. For automation, you can use Plink, what is a console equivalent of PuTTY.
See also Pipe PuTTY console to Python script
Though you should use Paramiko. It does not fail to display/print the output of commands like "top". It' not what it is for. You have to attach it to a terminal to achieve what you want. See Running interactive commands in Paramiko.
Or for automation, you better run the top non-interactively. See your other question Collect output from top command using Paramiko in Python.
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.
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
I have web application on Flask and user can send some request which my script is processing and then, running another script in python in the console with some parameters like this:
import sys
os.system('python start.py -u 100 -p 122224')
All works good, but now I want controlling all running copies of my script like start, stop and pause.
How i can do this without crutches?
Check subprocess and multiprocessing modules. The first one allows you to execute external application. To use the second one, you'll be required to call some python code, but the management capabilities should be much wider.
I have a python script that needs to send control C to the mac terminal. I've tried sending the plain text "^C" but I get back that the terminal does not recognize the command. (The terminal meaning the pseudo terminal that python creates)
Basically, I am using the terminal to run an old Unix Executable and the only way that I can think of to terminate this gracefully is to send the interrupt signal. Is there any way I can fool the terminal into thinking that I pressed control C?
Thanks in advance!
You can explicitly send the SIGINT signal to the process if you can get its PID using os.kill.
os.kill(pid, signal.SIGINT)
This will require you to instrument your script to grab the process PID, but it's the best way to emulate the "ctrl-c" behavior.
If you open the process using subprocess's Popen, you should be able to send a control signal like this:
proc.send_signal(signal.SIGINT)
You'll need to import signal to get SIGINT.