Using paramiko when a unix server is using VShell - python

Use case
On a unix server , when login manually ,opens a command shell of its own to run the command.
I am trying to automate this by using paramiko , however , somehow i am not able to execute the command on command shell using paramiko
What i have done ?
I created a simple script which is able to make connection, but its not executing command on Vshell as the ouput is always coming empty.
import paramiko
import sys
ssh_client=paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=sys.argv[1],port=sys.argv[2],username=sys.argv[3],password=sys.argv[4])
command="show hwid"
stdin,stdout,stderr=ssh_client.exec_command(command)
out=stdout.read()
print out
err=stderr.read()
print err
ssh_client.close()
The same script runs perfectly fine , when its used on server where vshell is not being used
Anyhelp or suggestion on this?

stdin,stdout,stderr=ssh_client.exec_command(command)
Regarding this line of code, I suspect that the SSH server is not properly configured to allow commands to be executed in this way (this is the equivalent of ssh myserver show hwid, rather than typing it into the terminal after login).
You might want to imitate the behaviour of typing the command in after logging into the server, and for that I think this is appropriate:
shell = ssh_client.invoke_shell()
stdin, stdout, stderr = shell.exec_command(command)

Related

How to run two applications (deamon and client) at the same time in single SSH using Python Paramiko

I want to run client and daemon application which responds to client in the same time.
Connection established to SSH using Paramiko. But I could not run both daemon and client in the same time.
How to do this with Paramiko?
Here the expectation is, client provide input as 1,2,3 and daemon responds to each input.
Both run in the same SSH.
Could any one help me with this?
I assume you can use simple shell syntax to achieve what you need. You do not need any fancy code in Python/Paramiko.
Assuming *nix server, see How do I run multiple background commands in bash in a single line?
To run (any) command in Paramiko, see Execute command and wait for it to finish with Python Paramiko
So probably like this:
stdin, stdout, stderr = ssh_client.exec_command("deamon & client")
stdout.channel.set_combine_stderr(True)
output = stdout.readlines()
If you need to somehow run the two commands (deamon and clinet) independenty for a better control, you can start here:
Run multiple commands in different SSH servers in parallel using Python Paramiko
Except that you do not need to open multiple connections (SSHClient). You will just call SSHClient.exec_command twice on the same SSHClient instance.

How to read and write directly to the CMD prompt on Windows?

I know others have asked similar questions to this, but what I want to know is whether or not there is a way to simply open a cmd window (on windows 10), leave it open and have a python script automatically type into it.
What I actually need to do is SSH into a remote computer and then from that remote computer, run IDL commands. I have not found a way to do this with subprocess Popen or with Paramiko to SSH. In the case of subprocess, I can't get past authentication to get into the host, i.e. I can't figure out how to type a password in. With Paramiko I am able to get into the remote computer but once there I can't get my IDL code to run, and if it does run it just hangs on that command and won't output anything, even after closing.
It seems to me that rather than sending commands directly to cmd through a subprocess or os command, it would make it much easier if I could just send a string to an open cmd window and have it execute the command and read the result. I'm going through a remote computer and then running IDL code on that remote computer so there are two layers that python has to get through. If I could just write in the cmd terminal it would make my life much easier, rudimentary as it is.
Apologies if I don't have the right lingo with all of this, I'm definitely not a network programmer.
Below is my attempt to use Paramiko. The "ls" command works and the contents of the folder I'm in are printed so I know I've accessed the remote computer, but my idl command does not print anything. Printing the output from the "idl" command itself just causes the program to hang there.
import paramiko
host = "<hostname>"
user = "<myusername>"
password = input("pass:")
client = paramiko.client.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username=user, password=password)
_stdin, _stdout,_stderr = client.exec_command("ls", get_pty=True)
print(_stdout.read().decode())
_stdin, _stdout,_stderr = client.exec_command("idl")
_stdin, _stdout,_stderr = client.exec_command("<my command>")
print(_stdout.read().decode())
client.close()
I made much less progress with os and/or subprocess as I can't even get into the remote computer with either of those.

Unable to import module when using paramiko sshclient [duplicate]

I am connecting to SSH via terminal (on Mac) and run a Paramiko Python script and for some reason, the two sessions seem to behave differently. The PATH environment variable is different in these cases.
This is the code I run:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='myuser',password='mypass')
stdin, stdout, stderr =ssh.exec_command('echo $PATH')
print (stdout.readlines())
Any idea why the environment variables are different?
And how can I fix it?
The SSHClient.exec_command by default does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced (particularly for non-interactive sessions, .bash_profile is not sourced). And/or different branches in the scripts are taken, based on an absence/presence of TERM environment variable.
To emulate the default Paramiko behavior with the ssh, use the -T switch:
ssh -T myuser#host
See the ssh man:
-T Disable pseudo-tty allocation.
Contrary, to emulate the default ssh behavior with Paramiko, set the get_pty parameter of the exec_command to True:
def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):
Though rather than working around the issue by allocating the pseudo terminal in Paramiko, you should better fix your startup scripts to set the same PATH for all sessions.
For that see Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command.
Working with the Channel object instead of the SSHClient object solved my problem.
chan=ssh.invoke_shell()
chan.send('echo $PATH\n')
print (chan.recv(1024))
For more details, see the documentation

How do I use PuTTY to execute commands on my server from a script?

With the ssh command one can pass it arguments to tell it to run commands on the remote server. I am trying to achieve the same thing, but with PuTTY.
I have PuTTY on my Windows machine, installed to C:. I am trying to invoke it from a local Python script, and have it invoke a command show system info on the server.
This is the sort of pseudo-Python that I am thinking of:
import ssh
server=ssh.Connection(host='10.201.20.240')
result=server.execute('show system info')
and more specifically using PuTTY from the Python script, something like this (which is of course not right, otherwise I wouldn't be asking this)
command = '"c:\Putty\putty.exe" -ssh user#10.201.20.240 -pw admin 10.201.20.240 '
result=command.execute('show system info')
subprocess.Popen(command)
If this were the ssh command I would be using ssh … user#10.201.20.240 show system info and suchlike.
What is the command-line syntax for the Windows PuTTY program for doing this?

Any substitutes for pexpect?

I am writing a script using python pexpect to execute another script on a remote machine. It works fine in normal cases, but if there is a time.sleep in the remote script, it fails.
I want to get to the remote machine, start the script in the background and get out. Is this possible ?
Can someone suggest an alternative or let me know how to get around this issue?
Have you considered paramiko?
Here's an example ...
#!/usr/bin/env python
import paramiko
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect(hostname='example.com', port=22, username='sethu', password='****')
ssh.exec_command('nohup sleep 300 &')
ssh.close()

Categories

Resources