I am writing a tkinter script which accepts a linux command from the UI. Once the submit button is clicked,I want to run this command that I got from the UI on a remote linux server and collect the output and display on the Tkinter window.
Regarding the tkinter parts, i am doing fine. the problem is when I wanna execute this command on the remote server and collect the output.
I will be running my program in a Virtual Environment of Conda
on a small research on google the most common solution I saw was the usage of fabric as shown here in this link
other solutions which I saw was the usage of plink and popen.
But I am not clear as to where I will mention the host name and password to connect to the remote server with any of the solutions stated above. How I will send my command and receive the output back to my tkinter flow. Is there way that I can understand if the command I executed failed because of some reason?
Any help on this will be appreciated! thanks in advance
So i found the solution i was looking for.. may be i did not read the docs which i surfed before properly..
here its
def connect():
print "starting to connect"
env.host_string = 'vpnuser#10.0.0.70'
env.password = "vpnuser "
run("ls -lrth")
put this in a fabfile.py file and run it like this
fab -a connect
That is it !
You want to use host_string to dynamically specify what the destination is. Change it before executing commands.
An example would be:
from fabric.api import run, env
env.host_string = 'user#host.com'
def ls():
run("ls")
Related
I am trying to run a script over SSH on a remote computer (the script is located on the remote computer). However, when I run Paramiko, all I'm doing is this:
ssh = paramiko.SSHClient()
ssh.connect(-----blacked out-----)
ssh.exec_command("python script.py")
But it's not even executing the command. The script just runs a couple command line commands. The script.py file works just fine if I run it on the remote computer through the remote computer's terminal, but it won't when I try to use ssh to do it like above with paramiko.
You might need to pass the full path to python and/or to the script, sometimes when not executing in terminal/interactive (tty) mode the path is not found as it does not load the profile scripts you would load during an interactive shell.
Without any info I'd guess that it outputs info which you don't read so it blocks and waits until you do... It's like echoing into the pipe when there is nothing on the other side...
I'd recommend looking into http://stackoverflow.com/a/32758464
I had faced a similar problem. In my case, I was executing another process from the ps1 file and the ps1 file was given in the ssh.exec_command() function.
my code flow was
ssh = paramiko.SSHClient()
ssh.connect(Host, Port, Username, Passsword)
ssh.exec_command(run.ps1)
# ----------------------
# As per the Expectation :
# -> run.ps1 will execute on remote
# -> run.ps1 contains "start-process notepad.exe"
# -> So, it should spawn a fresh notepad process
# ----------------------
But, notepad.exe was not started on the remote system
I made the following changes referring to other solutions :
Converted all single file paths to absolute paths.
Added a wait in the run.ps1 file until the child completes its execution
Passed argument in exec_command as "powershell.exe -File Absolute/path/of/file.ps1"
maintained log file into paramiko code as paramiko.util.log_to_file('sssh.log')
This time I was able to see that Notepad.exe was running in the background
I hope it will help with the above question
I'm trying to use fabric in python to send commands to a program on another machine.
This code works fine:
from fabric.api import env, run
env.host_string = 'xxx.xxx.xxx.xxx'
env.user = 'username'
env.password = 'password'
run('ls')
But when running
run('rostopic list')
I get
Warning: run() received nonzero return code 127 while executing 'rostopic list'!
'/bin/bash: rostopic: command not found'
However on the machine itself if I run
rostopic list
it runs as it's supposed to
I'm not sure how to proceed and I don't understand why it's not working with fabric. FYI I tried implementing this with paramiko but I also run into problems, however it works fine with pxssh. The issue is that I need this to work on Windows and pxssh isn't compatible. How can I make this command work with fabric?
From the comments you've made about the pathing issues, it sounds like you will need to use some combination of the path, cd, and/or prefix context managers in order to run ROS (Robot Operating System) commands over an SSH connection. You might also wish to troubleshoot by getting Fabric completely out of the picture, and instead work on getting the command to work via ssh -t, like so:
$ ssh user#machine -t "cd /my/home/directory && /opt/ros/indigo/bin/rostopic list"
An example using context managers with Fabric would look like this:
with path('/opt/ros/indigo/bin/'):
with prefix('always run this command'):
with cd('/my/special/directory'):
run('rostopic list')
That's pretty contrived, but hopefully illustrates the point. Regardless, I would first make sure that you can run the command via ssh -t. Solving that problem will likely lead you to the correct way to make this happen with Fabric.
As a side/related consideration: is this a virtual environment on your remote machine? You could use the prefix context manager to activate it, like so:
with prefix('/opt/ros/indigo/bin/activate'):
run('rostopic list')
Or using ssh -t, you could execute:
$ ssh user#machine -t "/opt/ros/indigo/bin/activate && rostopic list"
I have looked into using pxssh ,subprocess and paramiko but have found no success. What I am ultimately trying to do is figure out a way to not only use SSH to access a server and execute commands using a python script and finish there, but also have it open an instance of the terminal after executing all the commands for continued use.
Currently the server has modules that clients have to manually activate using commands after they have established an SSH connection.
For example:
module python
This command would give the user access to python.
Following this the user would then be able to use python and all its commands through the ssh connection in the terminal.
The issue I have with the methods listed earlier for executing these commands is that it does not display an instance of the terminal. It successfully executes the commands but since these commands have to be executed every time a new SSH connection is established it's worthless unless I can get essentially a copy of the terminal that the Python script executed and loaded up all the modules with.
Does any one have a solution to this? I've scoured the web for hours to no success.
This is a very difficult issue to explain so if anything is unclear please ask me and I will try my best to rephrase things. I am very new to all this.
I am trying to open an interactive ssh shell through fabric.
Requirements:
Use fabrics hosts in the connection string to remote
Open fully interactive shell in current terminal
Works on osx and ubuntu
No need for data transfer between fabric/python and remote. So fabric task can end in background.
So far:
fabfile.py:
def test_ssh():
from subprocess import Popen
Popen('ssh user#1.2.3.4 -i "bla.pem"', shell=True)
In terminal:
localprompt$ fab test_ssh
localprompt$ tcsetattr: Input/output error
[remote ubuntu welcome here]
remoteprompt$ |
Then if I try to input a command on the remote prompt it is executed locally and I drop back to the local prompt.
Does anyone know a solution?
Note: I am aware of fabrics open_shell, but this does not work for me since the stdout lags behind, rendering this unusable.
A slight modification does the trick:
def test_ssh():
from subprocess import call
call('ssh user#1.2.3.4 -i "bla.pem"', shell=True)
As the answer to this question suggests the error suggests the error comes from the inability of ssh to connect to the stdin/out of a process in the background.
With call the fabric task does not end in the background, but I am fine with that as long as as it is not interfering with my stdin/out.
I want to connect to putty and want to do few step:
login to Putty
type few command to bring down the server
Traverse to the particular path
Remove the file from the directory
Again start the server
I need to write the code in windows. But my server is in linux.
How shall I proceed?
Thanks in advance
What you need is Paramiko, but it may be a little complicated for a beginner.
For simple, repetitive tasks you may use my script - it is located on GitHub (https://github.com/tadeck/ssh-matic) and was created to learn some Python. It is based on someone else's friendly SSH Python interface to Paramiko (code accessible here).
Using the mentioned SSH module connecting to server and executing a command is rather simple:
import ssh
server = ssh.Connection(host='host', username='user', private_key='key_path')
result = server.execute('your command')
Basically what you need is not PuTTy, but a SSH module to Python. This module should work both on Windows and Linux. Using my script you will only need to work on the command you want to invoke, plus adjust the code to your needs.
Good luck. Tell me if it helped.
from pywinauto.application import Application
import time
app = Application ().Start (cmd_line=u'putty -ssh user_name#10.70.15.175')
putty = app.PuTTY
putty.Wait ('ready')
time.sleep (1)
putty.TypeKeys ("password")
putty.TypeKeys ("{ENTER}")
time.sleep (1)
putty.TypeKeys ("ls")
putty.TypeKeys ("{ENTER}")
I am using python 2.7. Code is running on Windows, and connect to remote Linux. it is working in my environment.
You could do this:
# Use plink to open a connection to the remote shell
command = "plink.exe -ssh %s -batch" % credentials
sp = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# Send commands to the shell as if they were read from a shell script
sp.stdin.write("command1\n")
sp.stdin.write("command2\n")
sp.stdin.close()
# read out the answers, if needed
ans = sp.stdout.read()
sp.wait()
For credentials, it is best to put the name of a PuTTY connection profile, ready with the username set and a SSH key.
you can use code similar to:
command = "plink.exe -ssh username#" + hostname + " -pw password -batch \"export DISPLAY='" + hostname + "/unix:0.0' ; "
which will open an ssh to the desired hostname using username and password
shutdown:
command += "sudo /sbin/halt\""
reboot:
command += "sudo /sbin/reboot\""
add your other commands using the same method as above,
run the command with:
pid = subprocess.Popen(command).pid
As pointed out by Tadeck, this will only work on a windows machine attempting to connect to a linux machine.