Python Script to SSH - python

I am a beginner trying to do SSH writing a basic code, I have tried everything not able to debug this , My code is as follows :
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print ("1")
ssh.connect('196.5.5.6', username='abc', password='abc')
print ("2")
stdin, stdout, stderr = ssh.exec_command('show version')
print ("3")
output= stdout.readlines()
print ("4")
print(output)
Output I get is 1
2
3
At 4 it get's stuck somewhere , there is problem that I am not able to fetch the data , Please help anyone. Code just hangs at the output step. Everywhere the solution is totally same.

You should enter commands try this
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print ("1")
ssh.connect('ip', username='user', password='pass')
print ("2")
stdin, stdout, stderr = ssh.exec_command('show version')
print ("3")
stdin,stdout,stderr = ssh.exec_command("ls /")
print stdout.readlines()

You don't need to do readlines() on stdin. You can print it directly. readlines() expect a file to be opened and read from the file. Whereas stdin, stdout, stderr are not files, rather a block of strings ( or string buffer used in paramiko channel). If you check the type of stdin, stdout, stderr, you will find <class 'paramiko.channel.ChannelFile'>, which are not exactly files, but are file like objects created to store the buffers in paramiko channel.
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print 1
ssh.connect('196.5.5.6', username='abc', password='abc')
print 2
stdin, stdout, stderr = ssh.exec_command('show version')
print 3
output= stdin
print 4
print(output)
print '---', stdout
print '---==', stderr

Related

I'm writing a paramiko common method to accept stdin and run command on other node [duplicate]

I'm having a problem with a ShoreTel voice switch, and I'm trying to use Paramiko to jump into it and run a couple commands. What I believe the problem might be, is that the ShoreTel CLI gives different prompts than the standard Linux $. It would look like this:
server1$:stcli
Mitel>gotoshell
CLI> (This is where I need to enter 'hapi_debug=1')
Is Python still expecting that $, or am I missing something else?
I thought it might be a time thing, so I put those time.sleep(1) between commands. Still doesn't seem to be taking.
import paramiko
import time
keyfile = "****"
User = "***"
ip = "****"
command1 = "stcli"
command2 = "gotoshell"
command4 = "hapi_debug=1"
ssh = paramiko.SSHClient()
print('paramikoing...')
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname = ip, username = User, key_filename = keyfile)
print('giving er a go...')
ssh.invoke_shell()
stdin, stdout, stderr = ssh.exec_command(command1)
time.sleep(1)
stdin, stdout, stderr = ssh.exec_command(command2)
time.sleep(1)
stdin, stdout, stderr = ssh.exec_command(command4)
time.sleep(1)
print(stdout.read())
ssh.close()
print("complete")
What I would expect from the successful execution of this code, would be for the hapi_debug level to be 1. Which means that when I SSH into the thing, I would see those HAPI debugs populating. When I do, I do not see those debugs.
I assume that the gotoshell and hapi_debug=1 are not top-level commands, but subcommands of the stcli. In other words, the stcli is kind of a shell.
In that case, you need to write the commands that you want to execute in the subshell to its stdin:
stdin, stdout, stderr = ssh.exec_command('stcli')
stdin.write('gotoshell\n')
stdin.write('hapi_debug=1\n')
stdin.flush()
If you call stdout.read afterwards, it will wait until the command stcli finishes. What it never does. If you wanted to keep reading the output, you need to send a command that terminates the subshell (typically exit\n).
stdin.write('exit\n')
stdin.flush()
print(stdout.read())

How to pass local variable to remote echo command?

import paramiko, commands
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.load_system_host_keys()
ssh_client.connect('xx.xx.x', username='abc',
key_filename='rsa')
line ="Hello"
stdin, stdout, stderr=ssh_client.exec_command('echo $line')
print stdout.readlines()
I want to pass the "line" content to echo. But i get
[u'\n'] as output.
I have also tried echo \$line, echo "$line". But not getting hello as output.
The remote shell can't access to your program variables, the command must be composed before its launch.
stdin, stdout, stderr = ssh_client.exec_command('echo "{0}"'.format(line))
Be aware of safety issues (Thanks #Tripleee), in Python 3 use shlex.quote to increase the robustness of your code:
stdin, stdout, stderr = ssh_client.exec_command('echo {}'.format(quote(line)))

Python Code to get the files from remote host using Paramiko

import paramiko
paramiko.util.log_to_file(r'D:\logs\paramico.log')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('xxx.xxx.xx.xx', port=22, username='xxxxx', password='xxxxxx')
stdin, stdout, stderr = ssh.exec_command('ll')
output = stdout.readlines()
print '\n'.join(output)
print output
This is a linux host and I want to list the files/folders present in it. But, I am getting empty list [].
Can please any one suggest me how to proceed to list the contents present in that.
import paramiko
paramiko.util.log_to_file(r'D:\logs\paramico.log')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('xxx.xxx.xx.xx', port=22, username='xxxxx', password='xxxxxx')
stdin, stdout, stderr = ssh.exec_command('ls -al')
output = stdout.readlines()
output1 = stderr.readlines()
print '\n'.join(output)
print output
print output1
As my host has hidden files, I need to use ls -al

Please tell me why this deadlocks: Reading and writing from Paramiko exec_command() file-like objects -- ChannelFile.close() does not work

import paramiko, threading
def Reader(src):
while True:
data = src.readline()
if not data: break
print data
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("172.17.0.2", username="test", password="test")
stdin, stdout, stderr = client.exec_command("dd of=readme.txt")
reader = threading.Thread(target=Reader, args=(stderr, ))
reader.start()
stdin.write("some data")
stdin.flush()
stdin.close()
reader.join()
This code waits forever at the join(). If I remove the stderr writing thread it works as expected, with the correct text being written to the file 'readme.txt', but I then lose the dd stderr messages.
The probblem is in stdin.close(). According to Paramiko's doc (v1.16):
Warning: To correctly emulate the file object created from a socket’s makefile() method, a Channel and its ChannelFile should be able to be closed or garbage-collected independently. Currently, closing the ChannelFile does nothing but flush the buffer.
So you have to use stdin.channel.close().
UPDATE:
Since stdin, stdout and stderr all share one single channel, stdin.channel.close() will also close stderr so your Reader thread may get nothing. The solution is to use stdin.channel.shutdown_write() which disallows writing to the channel but still allows reading from the channel.
Verified it works fine:
[STEP 101] # cat foo.py
import paramiko, threading, paramiko
def Reader(src):
while True:
data = src.read()
if not data: break
print data,
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("10.11.12.13", username="root", password="password")
stdin, stdout, stderr = client.exec_command("dd of=/tmp/file")
reader = threading.Thread(target=Reader, args=(stderr,) )
reader.start()
stdin.write("some data")
stdin.flush()
stdin.channel.shutdown_write()
reader.join()
[STEP 102] # python foo.py
0+1 records in
0+1 records out
[STEP 103] #

Get Python Version from Remote Host with paramiko

I'm writting a Software to get some Information about Server
and i just want to get the python Version from an remote Server.
Here is my code:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.server, username=self.user, password=self.pass)
stdin, stdout, stderr = ssh.exec_command("/usr/bin/python -V")
stdin.flush()
data = stdout.readlines()
print data #just debug
ssh.close()
The print just returns "[]".
It's in stderr. Don't ask me why:
>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect('tek')
>>> stdin, stdout, stderr = ssh.exec_command('python --version')
>>> stdin.flush()
>>> data = stdout.readlines()
>>> data
[]
>>> data = stderr.readlines()
>>> data
['Python 2.6.6\n']

Categories