Python remote connection to Raspberry via SSH and mosquitto - python

I want add remote connection feature to my Raspberry PI device.
Program was written in python 3.5.
I use mosquitto to send command from my PC to Raspberry program which listen special "command_topic"
Command:
./remote.exp password ssh -R 19999:localhost:22 login#ip_host
remote.exp code:
#!/usr/bin/expect
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "assword:"
send "$password\r";
interact
I use class Process from module multiprocessing which runs
subprocess.checkout_output(command)
and when I run my program normally
"python3 main.py"
and then I use
mosquitto_pub -t "command_topic" -m "command"
it works. I get 19999 port on my PC but when I run my program in background
"nohup python3 main.py &"
I cannot get port and I don't know how to solve this?

Related

Python os how to accept verification for SSH key

So basically I have a function that launches a glue development endpoint, and I want to programmatically launch zeppelin, then use the IP from the endpoint to ssh into it with my local browser. To do so, I run the following commands in the terminal:
cd ~/zepp081
bin/zeppelin-daemon.sh start
ssh -i pem_file_path -NTL 9007:169.254.76.1:9007 glue#ip_address
When I run the last command, I get the prompt:
The authenticity of host 'ip_address' can't be established.
ECDSA key fingerprint is X.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
at which point I type yes and continue on with my life. I would like to automate this in python using the following command:
import os
ssh_string = "ssh -i pem_file_path -NTL 9007:169.254.76.1:9007 glue#ip_address"
os.system(f"cd ~/zepp081 && bin/zeppelin-daemon.sh start && {ssh_string}")
The first two commands in line 4 run successfully, but the third fails saying Host key verification failed. How can I update the command to have it continue connecting?
ssh -o "StrictHostKeyChecking=no" .....

Run python code on remote python process

I have to run python code on remote python process.
Normally, what I would do is:
ssh admin#localhost -p 61234
which opens a interactive python console and I can execute python code directly.
>>> print('3')
3
>>>
But I want to automate this and pass python code as parameter to ssh.
I tried following options:
ssh admin#localhost -v -p 61234 python logs.py
ssh admin#localhost -v -p 61234 nohup python logs.py
ssh admin#localhost -p 61234 < logs.py
cat logs.py | ssh admin#localhost -p 61234 python -
But all options give following error:
shell request failed on channel 0
logs.py:
#!/usr/bin/env python
# tried with and without first line.
print('3')
netstat -anp | grep 61234
tcp 0 0 127.0.0.1:61234 0.0.0.0:* LISTEN 6/python2.7
Is there a way to do this?
Pretty sure this is overkill, but who knows, maybe you need more than just a simple command in the future.
Paramiko package is what you're looking for. The project is full of demos which demonstrate how and in many different ways.
The function you'll find the most useful is paramiko.client.SSHClient.exec_command
Execute a command on the SSH server. A new Channel is opened and the
requested command is executed. The command’s input and output streams
are returned as Python file-like objects representing stdin, stdout,
and stderr.
Demos Folder
In-depth Testing
Interactive.py is a fully interactive TTY (remote terminal control functions).
PyCharm Professional Edition (Python IDE from JetBrains) has tools for remote development, including SSH remoting, and the ability to run a remote interpreter:

SSH session held open when running a forked script

I have a parent script (start.py) who's primary purpose is to start background processes and exit. When I ssh directly to remote_host and run the script, it works as expected.
[user#local_host ~]# ssh remote_host
user#remote_host's password: ****
[user#remote_host ~]# time python start.py --config_file /data/workload.pg
real 0m0.037s
user 0m0.025s
sys 0m0.012s
The exit code of this script:
[root#perf72 ~]# echo $?
0
To simplify, instead of establishing the ssh session first and running the command, I want to just execute the command remotely from local_host:
[user#local_host ~]# ssh -o StrictHostKeyChecking=no -i /tmp/tmpqcz5l5il user#remote_host -p 22 "python start.py --config_file /data/workload.pg"
real 12m6.594s
user 0m0.027s
sys 0m0.016s
The problem here is that the ssh session remains open during the life of the background processes and not the life of the start.py script which is less than one second. It should just disconnect when the start.py script exits, but it doesn't.
Do I need a specific sys.exit() signal in the start.py script which will prompt the ssh session to disconnect?
ssh is awaiting output on the called process's stdout, so it can print it if there is any. That file handle is inherited by the subprocesses you're spawning, so it's still open even though the python script has exited, and as long as it's open, ssh will keep waiting.
If you change your ssh command line to run the remote script as "python start.py --config_file /data/workload.pg > /dev/null" instead, the ssh connection will close as soon as the python script does.

Python: How to execute more than 1 command over SSH without loggin in every command

I need to execute 2 commands on a remote machine (Ubuntu Mate 16.04) over SSH using a Python script.
run_pigpiod_remote runs a daemon on a remote RPi, as noted from #Line0 in code below. #Line1 makes SSH link and execute the daemon pigpiod as needed.
In order to verify successful run, I wish to use pgrep -x pigpiod as noted in #Line2. As #Line2 is written- I need to enter password again.
How can I avoid entering password so many times (entering SSH, running sudo , and 3rd for #Line2 )
def run_pigpiod_remote(adress):
if ip[0]==adress:
print(adress,"is a local machine")
run_pigpiod_local()
else: #Line0
print(adress," is a remote machine")
result = subprocess.run(['ssh','-t','guy#'+adress,'sudo','pigpiod']) #Line1
result2 = subprocess.run(['ssh','-t','guy#'+adress, "pgrep -x ", "pigpiod"]) #Line2
Try this
subprocess.run(['ssh','-t','guy#'+adress,'sudo pigpiod && pgrep -x pigpiod'])

process is not going background

I am running the python script shown below. The script does a ssh to the remote machine and runs a c program in the background. But on running the python script I get the following output:
This above means that a.out was run and the pid is [1] 2115 .
However whn I login to the remote machine and check for a.out via 'ps' command I dont see it.
Another observation is that when i add the delay statement in the python script thread.sleep(20) like , and while the script is still runnuing,
if I check in the remote machine, a.out is active.
#!/usr/bin/python
import HostMod #where ssh function is wrote
COMMAND_PROMPT1 = '[#$] '
p = HostMod.HostModule()
obj1=p.HostLogin('10.200.2.197', 'root', 'newnet') #ssh connection to remote system
obj1.sendline ('./a.out > test.txt &') #sending program to remote machine to executethere
obj1.expect (COMMAND_PROMPT1)
print obj1.before
#a.out program
int main()
{
while(1)
{
sleep(10);
}
return 0;
}
please try giving absolute path of ./a.out
Try using nohup
...
obj1.sendline ('nohup ./a.out > test.txt &') #sending program to remote machine to executethere
but you should really not use a shell to invoke commands over ssh. The ssh protocol has builtin support for running commands. I am not sure how your HostMod module works, but you could try this from your shell (would be easy to port to use subprocess):
ssh somehost nohup sleep 20
<Ctrl+C>
ssh somehost
ps ax | grep sleep
And you should see your sleep process still running. This method does not instantiate a shell, which is much more reliable, since you may or may not have control over which shell is run, what is in your ~/.(...)rc files, etc. All in all, much more portable.

Categories

Resources