Code Monkey home page Code Monkey logo

paramiko-expect's Introduction

Paramiko Expect

Paramiko Expect Logo

Artwork courtesy of Open Clip Art Library

Introduction

Paramiko Expect provides an expect-like extension for the Paramiko SSH library which allows scripts to fully interact with hosts via a true SSH connection.

The class is constructed with an SSH Client object (this will likely be extended to support a transport in future for more flexibility).

Quick Start

To install paramiko-expect, simply run the following at your prompt:

# from pypi
pip install paramiko-expect

# from source
pip install git+https://github.com/fgimian/paramiko-expect.git

So let's check out how it works in general (please see paramiko_expect-demo.py for the complete code):

# Connect to the host
client.connect(hostname=hostname, username=username, password=password)

# Create a client interaction class which will interact with the host
interact = SSHClientInteraction(client, timeout=10, display=True)
interact.expect(prompt)

# Run the first command and capture the cleaned output, if you want the output
# without cleaning, simply grab current_output instead.
interact.send('uname -a')
interact.expect(prompt)
cmd_output_uname = interact.current_output_clean

# Now let's do the same for the ls command but also set a timeout for this
# specific expect (overriding the default timeout)
interact.send('ls -l /')
interact.expect(prompt, timeout=5)
cmd_output_ls = interact.current_output_clean

# To expect multiple expressions, just use a list.  You can also selectively
# take action based on what was matched.

# Method 1: You may use the last_match property to find out what was matched
interact.send('~/paramiko_expect-demo-helper.py')
interact.expect([prompt, 'Please enter your name: '])
if interact.last_match == 'Please enter your name: ':
    interact.send('Fotis Gimian')
    interact.expect(prompt)

# Method 2: You may use the matched index to determine the last match (like pexpect)
interact.send('~/paramiko_expect-demo-helper.py')
found_index = interact.expect([prompt, 'Please enter your name: '])
if found_index == 1:
    interact.send('Fotis Gimian')
    interact.expect(prompt)

# Send the exit command and expect EOF (a closed session)
interact.send('exit')
interact.expect()

# Print the output of each command
print '-'*79
print 'Cleaned Command Output'
print '-'*79
print 'uname -a output:'
print cmd_output_uname
print 'ls -l / output:'
print cmd_output_ls

Important: Before running this script, be sure to place paramiko_expect-demo-helper.py in ~.

The print statements at the bottom of the script provide the following output:

-------------------------------------------------------------------------------
Cleaned Command Output
-------------------------------------------------------------------------------
uname -a output:
Linux fotsies-ubuntu-testlab 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

ls -l / output:
total 77
drwxr-xr-x  2 root root  4096 May  1 22:21 bin
drwxr-xr-x  4 root root  1024 May  1 22:22 boot
drwxr-xr-x 15 root root  4300 Jun 12 15:00 dev
drwxr-xr-x 90 root root  4096 Jun 12 16:45 etc
drwxr-xr-x  4 root root  4096 May  1 23:37 home
lrwxrwxrwx  1 root root    33 May  1 22:18 initrd.img -> /boot/initrd.img-3.2.0-23-generic
drwxr-xr-x 18 root root  4096 May  1 22:21 lib
drwxr-xr-x  2 root root  4096 May  1 22:17 lib64
drwx------  2 root root 16384 May  1 22:17 lost+found
drwxr-xr-x  4 root root  4096 May  1 22:18 media
drwxr-xr-x  2 root root  4096 Apr 19 19:32 mnt
drwxr-xr-x  2 root root  4096 May  1 22:17 opt
dr-xr-xr-x 84 root root     0 Jun 12 15:00 proc
drwx------  3 root root  4096 May 30 23:32 root
drwxr-xr-x 15 root root   560 Jun 12 17:02 run
drwxr-xr-x  2 root root  4096 Jun  4 20:59 sbin
drwxr-xr-x  2 root root  4096 Mar  6 04:54 selinux
drwxr-xr-x  2 root root  4096 May  1 22:17 srv
drwxr-xr-x 13 root root     0 Jun 12 15:00 sys
drwxrwxrwt  2 root root  4096 Jun 12 16:17 tmp
drwxr-xr-x 10 root root  4096 May  1 22:17 usr
drwxr-xr-x 12 root root  4096 Jun 12 13:16 var
lrwxrwxrwx  1 root root    29 May  1 22:18 vmlinuz -> boot/vmlinuz-3.2.0-23-generic

For interacting with tail-like scripts, we can use the tail function (please see paramiko_expect-tail-demo.py for the complete code):

# Connect to the host
client.connect(hostname=hostname, username=username, password=password)

# Create a client interaction class which will interact with the host
interact = SSHClientInteraction(client, timeout=10, display=False)
interact.expect(prompt)

# Send the tail command
interact.send('tail -f /var/log/auth.log')

# Now let the class tail the file for us
interact.tail(line_prefix=hostname+': ')

The true power of the tail function will become more apparent when you check out the Multi-SSH library. Ever thought about tailing a log on multiple servers? Well dream no more my friend, it's here!

Tests

Not full coverage yet, and assumes you have docker setup:

pip install -r requirements-test.txt
docker run -d -p 2222:22 -v `pwd`/examples:/examples -v `pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  docker.io/panubo/sshd
pytest -s --cov paramiko_expect --cov-report term-missing

Contributions

  • Israel Fruchter (@fruch) - Tests / CI / Uploads to Pypi
  • Kiseok Kim (@kiseok7) - Vagrent image

License

Paramiko Expect is released under the MIT license. Please see the LICENSE file for more details.

paramiko-expect's People

Contributors

dalrrard avatar droscy avatar fgimian avatar fruch avatar karypid avatar max-lobur avatar oskrdt avatar pw201 avatar rockallite avatar sriramkannan95 avatar vinaykumar-c avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paramiko-expect's Issues

Buffer size for ssh session in paramiko-expect

I am using paramiko-expect to send commands to a server. It is working as expected except when there is pagination options in the returned prompt. In that case, the output text is missing the first character in the output of each new page command and sometimes hangs and doesn't see the matching regular expression which was displayed. Putting buffer_size=1 is the only thing that fixes it for me 100%. Even putting the buffer size to 32 shows the same issues again.

That solution is too slow though, is there anything else I can do?

interact = SSHClientInteraction(ssh, timeout=300, display=True, buffer_size=1)  
output = ''
command = "file search activelog /platform/log/certm.log INFO"
not_done = True
interact.send(command)
while not_done:
    interact_index = interact.expect(['.*Press <enter> for 1 line, <space> for one page, or <q> to quit', '.*Search completed'])
    output += interact.current_output_clean
    if interact_index == 0:
        time.sleep(1)
        interact.send(' ')
    else:
        not_done = False
print(output)

ssh.close()

IndexError when you get an empty buffer

With an SSH session active, reboot or disable networking on the target machine (to close the remote end of the SSH session). Then, try to use paramiko-expect to scan through the shell. I would expect a socket.timeout, but instead you get an IndexError.

This is because the buffer is empty (on retrieval from remote connection), then you try to scan through the current output for the given regex strings, then try to directly access a 'found_pattern' that isn't actually found.

This could by solved by either converting the While loop to a While: Else (for when the buffer breaks out of the loop), or checking that there is actually a found pattern.

A better way to stop tail() call

paramiko-expect is a very useful addition to paramiko itself. The documentation could be improved to give more examples of how to use the timeout and other options.

Expect function not matching

I really like this module but im running into an issue getting the "expect" function to work correctly.
It seems as though its not reading the data form the buffer. Im no Python Wiz so im not totally sure
what the issue is but i can supply the error.

The code Logs in to the router just fine and the prompt i will get back is "FW80CM3911602851 #"
in my out put i do get "FW80CM3911602851 #" displayed back to the console but expect never
matches the out put.

im just matching this exactly just to make sure its matching correctly .. The issue is it dose not seem to be working .

Below is my testing code:

!/usr/bin/python2

import paramiko
from paramikoe import SSHClientInteraction
import traceback

def Main():

try:

    hostname = 'example.us'
    username = 'Uname'      
    password = 'passWord'  

    s = paramiko.SSHClient()
    s.load_system_host_keys()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    s.connect(hostname=hostname, username=username, password=password)
    interact = SSHClientInteraction(s, timeout=10, display=True)
    if interact.expect(re_strings='FW80CM3911602851 # ', timeout=60):
        print "passed"

except Exception:
    traceback.print_exc()
finally:
    try:
        s.close()
    except:
        pass

if name == "main":
Main()
author = 'todd'

Out put =

/usr/bin/python2.7 /home/todd/PycharmProjects/paramikoe-test/Main.py
FW80CM3911602851 #

Traceback (most recent call last):
File "/home/todd/PycharmProjects/paramikoe-test/Main.py", line 24, in Main
if interact.expect(re_strings='.FW80CM3911602851 # ', timeout=60):
File "/usr/local/lib/python2.7/dist-packages/paramikoe.py", line 122, in expect
buffer = self.channel.recv(self.buffer_size)
File "/usr/lib/python2.7/dist-packages/paramiko/channel.py", line 619, in recv
raise socket.timeout()
timeout

Process finished with exit code 0

null characters in interact.current_output_clean

On a Cisco ASA after doing a certificate request, there is a \x00 character in the output that I am having to use re.sub to remove.

This can be re-created on any Cisco ASA by creating a certificate request:

crypto ca trustpoint SSL-Trustpoint

channel.recv() problem

Hi,

I've experienced issue when trying to match against output when running .expect() right after .send(). Expect does not show output as with pexpect library. It return the command I've sent along with prompts instead of returning result of the command.
If I introduce certain delay after each .send() it tends to work more correctly.

Thanks, Dragan

"from paramiko_expect import SSHClientInteraction" fails to load library

Hi,

You might want to look into this since other people can run into this

pip-installed module

[qa-user@qa-driver ~]$ sudo pip install git+https://github.com/fgimian/paramiko-expect.git
[sudo] password for qa-user: 
Collecting git+https://github.com/fgimian/paramiko-expect.git
  Cloning https://github.com/fgimian/paramiko-expect.git to /tmp/pip-aqFZmx-build
Requirement already satisfied (use --upgrade to upgrade): paramiko>=1.10.1 in /usr/lib/python2.7/site-packages (from paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): cryptography>=1.1 in /usr/lib64/python2.7/site-packages (from paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): pyasn1>=0.1.7 in /usr/lib/python2.7/site-packages (from paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): idna>=2.0 in /usr/lib/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): six>=1.4.1 in /usr/lib/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/lib/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): enum34 in /usr/lib/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): ipaddress in /usr/lib/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): cffi>=1.4.1 in /usr/lib64/python2.7/site-packages (from cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Requirement already satisfied (use --upgrade to upgrade): pycparser in /usr/lib/python2.7/site-packages (from cffi>=1.4.1->cryptography>=1.1->paramiko>=1.10.1->paramiko-expect==0.2)
Installing collected packages: paramiko-expect
  Running setup.py install for paramiko-expect ... done
Successfully installed paramiko-expect-0.2

it was placed in the right location, although for some reason from paramiko_expect import SSHClientInteraction fails:

[qa-user@qa-driver ~]$ sudo pip show paramiko-expect
---
Metadata-Version: 1.0
Name: paramiko-expect
Version: 0.2
Summary: An expect-like extension for the Paramiko SSH library
Home-page: https://github.com/fgimian/paramiko-expect
Author: Fotis Gimian
Author-email: [email protected]
License: MIT
Location: /usr/lib/python2.7/site-packages
Requires: paramiko
Classifiers:

[qa-user@qa-driver ~]$ python paramiko_expect.pyc 
Traceback (most recent call last):
  File "paramiko_expect.py", line 3, in <module>
    from paramiko_expect import SSHClientInteraction
  File "/home/qa-user/paramiko_expect.py", line 3, in <module>
    from paramiko_expect import SSHClientInteraction
ImportError: cannot import name SSHClientInteraction

There is no problem with import paramiko that is also located in same directory: /usr/lib/python2.7/site-packages

[qa-user@qa-driver ~]$ sudo pip show paramiko
---
Metadata-Version: 2.0
Name: paramiko
Version: 2.1.1
Summary: SSH2 protocol library
Home-page: https://github.com/paramiko/paramiko/
Author: Jeff Forcier
Author-email: [email protected]
Installer: pip
License: LGPL
Location: /usr/lib/python2.7/site-packages
Requires: cryptography, pyasn1
Classifiers:
  Development Status :: 5 - Production/Stable
  Intended Audience :: Developers
  License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
  Operating System :: OS Independent
  Topic :: Internet
  Topic :: Security :: Cryptography
  Programming Language :: Python
  Programming Language :: Python :: 2
  Programming Language :: Python :: 2.6
  Programming Language :: Python :: 2.7
  Programming Language :: Python :: 3
  Programming Language :: Python :: 3.2
  Programming Language :: Python :: 3.3
  Programming Language :: Python :: 3.4
  Programming Language :: Python :: 3.5

and it does not look like permission issue either:

[qa-user@qa-driver ~]$ sudo python paramiko_expect.pyc 
Traceback (most recent call last):
  File "paramiko_expect.py", line 3, in <module>
    from paramiko_expect import SSHClientInteraction
  File "/home/qa-user/paramiko_expect.py", line 3, in <module>
    from paramiko_expect import SSHClientInteraction
ImportError: cannot import name SSHClientInteraction

Upload to PyPI?

This is a very useful package, but I don't seem to be able to find it on PyPI. Would it be possible to have the package uploaded to make installation of it easier?

typo in README

The readme has:

pip insall paramiko-expect

and should have "install" instead.

improper output with paramiko_expect's SSHClientInteraction when connected to windows

import traceback
import paramiko
from paramiko_expect import SSHClientInteraction

def main():
    # Set login credentials and the server prompt
    HOSTNAME = 'locallhost'
    USERNAME = 'Administrator'
    PASSWORD = 'password'
    PROMPT = r'.*>'

    # Create a new SSH client object
    client = paramiko.SSHClient()
    # Use SSH client to login
    try:
        # Set SSH key parameters to auto accept unknown hosts
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # Connect to the host
        client.connect(hostname=HOSTNAME, username=USERNAME, password=PASSWORD)

        # Create a client interaction class which will interact with the host
        with SSHClientInteraction(client, timeout=10, display=True) as interact:
            interact.send('dir')
            interact.expect(PROMPT)
            cmd_output_uname = interact.current_output_clean
            print(cmd_output_uname)

    except Exception:
        traceback.print_exc()
    finally:
        try:
            client.close()
        except:
            pass

if __name__ == '__main__':
    main()`

Following is the output:

Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.

administrator@xyz C:\Users\Administrator>dir
dir ir r
Volume in drive C has no label.
Volume Serial Number is ABCD

Directory of C:\Users\Administrator

06/25/2018 06:40 PM HH;24;27;37;40mMicrosoft Windows [Version 6.2.9200] H(c) 2012 Microsoft Corporation. All rights reserved.

Hadministrator@xyz C:\Users\Administrator>dir
Hdir HHir HHr
HH HH Volume in drive C has no label.
H Volume Serial Number is ABCD

H Directory of C:\Users\Administrator

Process finished with exit code 0

I see the output is improper and repeated multiple times like this "dir", "ir", "r". Similiar code works well for linux. I have tried modifying the SSHClientInteraction class from paramiko_expect.py but not successful in fixing this issue. I think this is a problem in reading byte stream from buffer in windows like here,

current_buffer = self.channel.recv(self.buffersize)

socket.timeout() raises AttributeError Exception

I'm always managing my exceptions in my code but I keep not getting the actual information of the "generic" Exception when this happens. I have at my code a part where I except Exception as e: and where I print the e but I keep getting "None". Using my debugger I saw this happening in that part. I wasn't able to print the information of the exception because of an Attribute not being found after socket.timeout() exception is risen.

image

Traceback (most recent call last):
  File "/Users/dglez/Library/Python/3.8/lib/python/site-packages/paramiko/channel.py", line 699, in recv
    out = self.in_buffer.read(nbytes, self.timeout)
  File "/Users/dglez/Library/Python/3.8/lib/python/site-packages/paramiko/buffered_pipe.py", line 164, in read
    raise PipeTimeout()
paramiko.buffered_pipe.PipeTimeout

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/dglez/myproject", line 1808, in myfunction
    myexpect.expect("some string.*", timeout=60)
  File "/Users/dglez/Library/Python/3.8/lib/python/site-packages/paramiko_expect.py", line 144, in expect
    current_buffer = self.channel.recv(self.buffer_size)
  File "/Users/dglez/Library/Python/3.8/lib/python/site-packages/paramiko/channel.py", line 701, in recv
    raise socket.timeout()
socket.timeout

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/dglez/.vscode/extensions/ms-python.python-2021.6.944021595/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_resolver.py", line 193, in _get_py_dictionary
    attr = getattr(var, name)
AttributeError: characters_written

Did I came to the right place to open this issue?

Tail Stop_callback() Example?

I am building a script to monitoring some build logs on a remote system when a user kicks off a build. I got the tail function working, and using a timeout function to stop it after X second of no input. I can see there is a stop_callback function that can break the tail function as well. This seems like a much cleaner way to do this. I can't seem to find any example that uses the stop_callback function, there there some place I can look for that?

My code:

    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname, port=port, username=username, password=password)
        interact = SSHClientInteraction(client, timeout=10, display=False)
        interact.send('tail -f file.txt')
        interact.tail(timeout=60)
    except KeyboardInterrupt:
        print ('Ctrl+C interruption detected, stopping tail')
        client.close()
    except Exception:
        #traceback.print_exc()
        client.close()
    finally:
        try:
            client.close()
        except:
            pass

Thanks

Django

I am trying to use interact.take_control() in django view which will be shown in browser and user will send
command from form. Does it possible, if not what should i do ?

paramiko-expect: expect loop take long time with a long output

Hi,

I am starting using python as migration for old tcl scripts. paramiko-expect has been working just perfect, thanks for the tool... but recently we faced this issue when we need to take a CLI output from our servers that is very long. we notice that expect command never ends and python starts to consume lot of CPU for long time.

we inspect the code and suspect this check for the prompt using the "self.current_output" start to get very slow.

do you see any way to optimize this part?

thank you!

invalid output

Hi,
when I use paramiko-expect, sometimes the output is invalid. To be specific, the printed cmd_output_2 is in fact output for some_command1. Sample code below.

        with SSHClientInteraction(client, timeout=10, display=False) as interact:
            interact.send('some_command1')
            interact.expect("some_prompt> ")
              cmd_output_1 = interact.current_output_clean
            interact.send('some_command2')
            interact.expect("some_prompt> ")
            cmd_output_2 = interact.current_output_clean
            #and later print (cmd_output_1) and print (cmd_output_2)

Anyway to expect password prompt?

I have a project in which I need to evaluate the password prompt during an SSH connection. I was using pexpect to spawn ssh and evaluate. This worked. However, my project needs to be run from AWS Lambda and there is no available ssh command.

Is there any way to get paramiko-expect to expect before "connect"? I have this:

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=instance_ip, username=test_user)
with SSHClientInteraction(client, timeout=10, display=True) as interact:
    i = interact.expect(['.*Enter your  Password:', '.*Password:'])

But this just gets "Authentication failed."

Any help would be appreciated.

Chris

How to keep my ssh connection alive

I am trying to ssh into remote server. I run some program which is like menu application. I went into menu 1 which has sub menu from 1 to 10. If i need to leave this connection and want to come back and want to join like where i was before. I am unable to do this . As Paramariko expect is closing connection after executing one set of command

Cannot interact with the shell interactively using paramiko-expect, getting socket.timeout() error.

Hi,

I'm new to python, so please bare with me.

My use case, is to interact with the shell interactively and at the same time verify the execution of commands, which I think this module fulfills it. But the problem is I'm not able to interact with the shell properly.

I've a server running, to which I can interact through shell, so basically I'm trying to automate this procedure.

I've edited following code but getting a socket timeout error at interact.prompt. Please suggest, what I'm doing wrong in this....

import traceback
import paramiko
from paramikoe import SSHClientInteraction

def main():

    # Set login credentials and the server prompt
    hostname = '10.97.121.35'
    username = 'admin'
    password = 'admin'
    prompt = 'admin@pjajoo-t420:/> '

    # Use SSH client to login
    try:

        # Create a new SSH client object
        client = paramiko.SSHClient()

        # Set SSH key parameters to auto accept unknown hosts
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # Connect to the host
        client.connect(hostname=hostname, username=username, password=password, port=2222)

        # Create a client interaction class which will interact with the host
        interact = SSHClientInteraction(client, timeout=10, display=True)   
        interact.expect(prompt)

        # Run the first command and capture the cleaned output, if you want
        # the output without cleaning, simply grab current_output instead.
        interact.send('ls')
    #print interact
        interact.expect(prompt)
        cmd_output_uname = interact.current_output_clean

        # Print the output of each command
        print '-'*79
        print 'Cleaned Command Output'
        print '-'*79
        print 'uname -a output:'
        print cmd_output_uname

    except Exception:
        traceback.print_exc()
    finally:
        try:
            client.close()
        except:
            pass

if __name__ == '__main__':
    main()

Basically it connects to the shell properly, but stops at first interact.expect(prompt) and gives me socket.timeout() as follows -

apps@ubuntu:~$ python paramikoe-demo.py 
    _____ _____    _      ____  _          _ _ 
 XXXX
XXX shell v1.2.0

Hit '<tab>' for a list of available commands
   and '[cmd] --help' for help on a specific command.
   or 'help [cmd]' to get detailed help on the command with samples.
Run 'logout' or 'exit' to exit the shell.

admin@pjajoo-t420:/> Traceback (most recent call last):
  File "paramikoe-demo.py", line 45, in main
    interact.expect(prompt)
  File "/usr/local/lib/python2.7/dist-packages/paramikoe.py", line 108, in expect
    buffer = self.channel.recv(self.buffer_size)
  File "/usr/local/lib/python2.7/dist-packages/paramiko/channel.py", line 586, in recv
    raise socket.timeout()
timeout

Assistance need to achieve this task using paramiko-expect

Currently this is what is do in Putty on windows on daily basis.

Click on my host then it prompts me like this, yes it has two level authentication

login as:      loginName(Then enter)
Password:   Password1(Then enter)
Username:  UserName(Then enter)
Password:   Password2(Then enter)
Then one more  Enter

Here I get my Required output shown on Putty , this is just a couple line of text which usually gets changed everyday.
So i need to capture this on a daily basis.

I am not sure is this the right way to write my code.
I am sure it gets connected to hostname on level 1, but second level username is not passed. So not sure what I am doing wrong.

import traceback
import paramiko
from paramiko_expect import SSHClientInteraction

client = paramiko.SSHClient()

# Set SSH key parameters to auto accept unknown hosts
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

hostname = 'MyCustomServer.com'
login = 'myFirstLevelLogin'
password1 = 'MyFirstPassword'
username = 'mySecondLevelLogin'
password2 = 'MySecondPassword'
prompt1 = 'Username:'
prompt2 = 'Password:'


# Connect to the host
client.connect(hostname=hostname, username=login, password=password1)

# Create a client interaction class which will interact with the host
interact = SSHClientInteraction(client, timeout=10, display=True)
interact.expect(prompt1)
interact.send('username')
interact.expect(prompt2)
interact.send(password2)
interact.expect('Not sure what to put here as i just press enter in my usual putty session ')
interact.send('I send enter key')
interact.expect('This is my final output its two lines of text no command prompt here(i mean the typical user@mymachine:$) this will not be found, this screen goes off after 5 seconds')

cmd_output = interact.current_output_clean

# Send the exit command and expect EOF (a closed session)
interact.send('exit')
interact.expect()

print (cmd_output)

Thank you for this wonderful package

Paramiko-expect timing out

Hi,

Today I was developping an application with paramiko-expect, I followed example steps by steps, but I still have an error and I didn't understand where I missed

Here is my code :

`#xxxx : for privacy on the post
try:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    ipList = open('iplist.txt', 'r')
    cmdList = open('cmdlist.txt', 'r')
    
    print('Authenticating with public key \'imported-openssh-key\'\nPassphrase for key \'imported-openssh-key\': ', end = '')
    
    while pwd == 0:
        try :
            password_pk = getpass.getpass('')
            k = paramiko.RSAKey.from_private_key_file(r'C:\Users\decoux\Downloads\[email protected]', password_pk) 
            pwd = 1
        except:
            print('Wrong passphrase')


    client.connect(hostname, username=username, pkey = k)

    pre_interact = SSHClientInteraction(client, timeout=20, display=True)
    pre_interact.expect('(ex: login@ip) ')                         # HERE IT BLOCK -> each expect blocks the program
    pre_interact.send('[email protected]')
    pre_interact.expect('xxxxx@xxxxx:~$ ') 

except Exception:
    traceback.print_exc()
finally:
    try:
        client.close()
    except:
        pass`

Thanks !

Long running commands are always failed with error message

I would like to execute some commands on the remote server . Usually that command took 1 hour to complete the task on the remote server .

But this module failed as below .

PROMPT = '.*$\s+'

Used the above mentioned PROMPT value.

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/paramiko/channel.py", line 699, in recv
out = self.in_buffer.read(nbytes, self.timeout)
File "/usr/local/lib/python3.7/site-packages/paramiko/buffered_pipe.py", line 164, in read
raise PipeTimeout()
paramiko.buffered_pipe.PipeTimeout

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "code.py", line 71, in main
interact.expect(PROMPT)
File "/usr/local/lib/python3.7/site-packages/paramiko_expect.py", line 144, in expect
current_buffer = self.channel.recv(self.buffer_size)
File "/usr/local/lib/python3.7/site-packages/paramiko/channel.py", line 701, in recv
raise socket.timeout()
socket.timeout

Kindly let me know your comments on this issue

Add display override for the "send" function

It would be great to be able to override "display" behavior in the send calls when needed, similarly to how timeout can be overridden in the expect calls.
It is very useful since "display" might not be needed in general, but might be needed for some specific send calls.

Python 3.x buffer usage?

Having a Python 3.4 conversion issue that I can't seem to solve:

prompt = 'router#'
interact.expect(prompt)

Throws:

Traceback (most recent call last):
File "./ssh-expect.py", line 37, in
interact.expect(prompt)
File "/usr/lib64/python3.4/site-packages/paramikoe.py", line 130, in expect
buffer = buffer.replace('\r', '')
TypeError: 'str' does not support the buffer interface

Which I see a lot in other code I write where using .decode('UTF-8') and .encode('UTF-8') get's me though, but in this case I get.

File "/usr/lib64/python3.4/site-packages/paramikoe.py", line 116, in expect
for re_string in re_strings
File "/usr/lib64/python3.4/site-packages/paramikoe.py", line 117, in
if re.match('.*\n' + re_string + '$',
TypeError: Can't convert 'int' object to str implicitly

Is there a method for Python 3.x for this module? :-D

issue in printing results (remote)

after I connected to a server and try to print results from the remote server
I got this with the results �[K
i tried to use .replace

interact.send("show int des | in JEDDAH-JEDDAH IP1009")
interact.expect('.#$')
show_inter = interact.current_output_clean
interact.send('exit')
interact.expect('.>\s')

photo5893351066563620839

Expect hanging when self.current_output is too large

I have a process that is monitoring the install/boot progress with paramiko expect, but when monitoring a specific very large system that produces a huge amount of output per minute, it seems that expect method hangs and it's not even failing for the timeout as it should.
When debugging, I realized that the condition where is trying to match the regex strings is rapidly increasing the time it takes to execute.

            not [re_string
                 for re_string in re_strings
                 if re.match(default_match_prefix + re_string + '$',
                             self.current_output, re.DOTALL)]

So it seems the time it takes to look for a match on self.current_output is taking more than the time the buffer gets filled up again.

Paramiko-expect socket-time out

Hi fgimian i am new in python and i have faced with problem, this error occure randomly. Sometimes cycle can be 3 and more itteration sometimes it error occure in first itterattion.

Thank you for the Help!

from __future__ import print_function
import os
import traceback
import paramiko.
from paramiko_expect import SSHClientInteraction
import re
import time

date = time.strftime("_%Y_%m_%d_%H_%M_%S")
host = '1.2.2.4'
user = '1233'
secret = '123'
#File with devices
devices = "devices".
ftp_srv = "1.0.1.5"
conf_path = "/var/ftp/"


l_dev = open(devices, 'r+')
dev = l_dev.readlines()
l_dev.close()


for i in dev:
    i = i.strip().split(' ')
    if i[0] in ["SWITCH"]:
        dev_name = (i[1][:-1])
        if not os.path.exists(conf_path + dev_name):
            os.makedirs(conf_path + dev_name)
            os.chmod(conf_path + dev_name, 655)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname=i[2], username=user, password=secret)

        with SSHClientInteraction(ssh, timeout=10, display=True) as interact:
            interact.expect(i[1])
            interact.send('copy running-config ftp:/' + dev_name + '/')
            interact.expect("Address or name of remote.*")
            interact.send(ftp_srv)
            interact.expect("Destination filename.*")
            interact.send(dev_name + '/' + dev_name + date)
            interact.send('exit')
            interact.expect()
            cmd_output_uname = interact.current_output_clean
        ssh.close()
        time.sleep(5)

FL-4_SW01#Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/paramiko/channel.py", line 683, in recv
out = self.in_buffer.read(nbytes, self.timeout)
File "/usr/local/lib/python3.7/site-packages/paramiko/buffered_pipe.py", line 160, in read
raise PipeTimeout()
paramiko.buffered_pipe.PipeTimeout

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "./coll_conf.py", line 39, in
interact.expect(i[1])
File "/usr/local/lib/python3.7/site-packages/paramiko_expect.py", line 144, in expect
current_buffer = self.channel.recv(self.buffer_size)
File "/usr/local/lib/python3.7/site-packages/paramiko/channel.py", line 685, in recv
raise socket.timeout()
socket.timeout

Does not strip all ANSI sequences correctly

The current code does not handle some ANSI sequences cleanly, for example ones that modify cursor position.

For example:
'\x1b[1;13r\x1b[1;1H\x1b[24;1HPress any key to continue\x1b[13;1H\x1b[?25h\x1b[24;27H\x1b[?6l\x1b[1;24r\x1b[?7l\x1b[2J\x1b[1;1H\x1b[1920;1920H\x1b[6n\x1b[1;1H'

is stripped to:
'rHHPress any key to continueH?25hH?6lr?7lH20;1920HnH'

Cannot install package paramiko_expect into server

Hello everyone,
I want to install package paramiko_expect to Unix server by pip .
For some reason , maybe firewall prevent I could not.
Is there any way to install paramiko_expect manually by file or any way that do not need yo use pip .

Testing take_control() to incress coverage

testing interactive stuff is a bit more complicated.
someone want to take it head on ? 🥇 (and a beer on me) for whom can make it, or at least share an example of how to do such type of tests.

Long commands break output cleaning

If you send a command whose length + the prompt length exceeds the tty_width, spaces are inserted into the command line that gets echoed back out at positions where it linewraps. This breaks output cleaning because the echoed command line no longer matches the input.

On my Ubuntu 16.04 box, my banner and prompt looks like this:

$ ssh localhost
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-83-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.

Last login: Fri Jul  7 02:33:10 2017 from 127.0.0.1
vmuser@vm:~$ 

Note that the prompt vmuser@vm:~$ has a space at the end, i.e. it is 13 characters long.

On this machine, running

import paramiko
import paramiko_expect as pe

if __name__ == "__main__":
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(hostname="localhost", username="vmuser")

    with pe.SSHClientInteraction(client, timeout=10, display=False, tty_width=40) as interact:
        user_prompt = r".*\$\s+"
        interact.expect(user_prompt)

        interact.send("echo " + "a"*100)
        interact.expect(user_prompt)
        cmd_output = interact.current_output_clean

        print(cmd_output)

prints:

vmuser@vm:~/paramiko-expect$ ./main.py 
echo aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

vmuser@vm:~/paramiko-expect$

Replace the "a"*100 with "a"*10, and it works as expected:

vmuser@vm:~/paramiko-expect$ ./main.py 
aaaaaaaaaa

vmuser@vm:~/paramiko-expect$

EXCESS TIME RECV_READY TIMEOUT, did you expect() before a send() on offical sample.

I've tried the paramiko_expect-tail-demo sample since I started to receive the "excess time RECV_READY..." err on my code .
tried sample and got the prompt too.
i noticed the following:
line 39 : interact.expect(prompt)

    # Send the tail command
      interact.send('tail -f /var/log/syslog')

so, is this example working? as the message implies that the code order will fail.

Hardcoded $ in re_string

Hi!
I'm running Centos and there is no $ symbol in prompt, it has # instead.
In other operations, e.g. changing user password, there are no symbols ($, #) at all.

So, may be it should better not to include such symbols in re_strings in expect method?

After I've removed + '$' everything works fine.

How to save the output of unix command into variable and do not show output to monitor

Hello ,
I have a question and need your help.
my code is :
with SSHClientInteraction(client, timeout=10, display=True) as interact:
interact.expect(PROMPT)
interact.send(command) (ex : ls -lrth)
interact.expect(PROMPT,timeout=20)
cmd_output_command = interact.current_output_clean
I do not want the output show on the monitor after I send(command) , is there anyway to hidden those. I just need save output to variable and will re-format the output appropriate with requirement.

Problem with sending long commands

Hi,

I made a wrapper for Paramiko, which helps me to connect to (mainly Cisco IOS-XR) devices using Linux server as jumphost. So I first SSH to jumphost using Paramiko and from there I jump further using Linux ssh. However, when sending slightly longer commands in Paramiko shell, they get strangely echoes, for example:

RP/0/RP0/CPU0:ROUTER#show rpl route-policy TESTING-ROUTING-POLICY deta�����������������������������������������������������$NG-ROUTING-POLICY

The command that should have been sent it:
show rpl route-policy TESTING-ROUTING-POLICY detail

Here is the code excerpt that is responsible for receiving data:

` def expect(self, patterns, timeout=0):
self.__before.clear()
wait = 0

    if not isinstance(patterns, list):
        patterns = [patterns]

    while True:
        time.sleep(SSH.poll_sleep) # default 0.5s
        if self.shell.recv_ready():
            found_pattern = None
            received = self.shell.recv(8192)
            received = received.decode()

            if self.doprint:
                print(received, end='')

.....`

Do you know what might be causing the issue like that?
Thanks, Dragan

string.split() causes extraneous "u" character in newly created list

I'm doing a bit of cli scraping with paramiko and had written it with timeouts originally and everything was working fine. I came across the need for "expect" on a day with higher network latency so I began that implementation. Everything works just the same except that when I run the command string6 = string5.split("\t") I all of a sudden get an extra 'u' character before each entry in the list. I've set breakpoints and don't see this behavior in the actual variables themselves, only when (during debugging) I print(string6) to verify the CLI output's massaging along the way.

Here's a snippit of the data

#tab delimited string 5
string5: Endcrinology 0 0:00 0:00 0 0 0:00

#string 5 split using string.split() function and saving into variable string6
string6: [u'Endcrinology', u'', u'0', u'0:00', u'0:00', u'0', u'0', u'0:00'

When running this exact same script that I'd previously written without the use of paramiko-expect (and it's objects) I get the expected output of:

string6: ['Endcrinology', '', '0', '0:00', '0:00', '0', '0', '0:00'

Also, yes I know Endocrinology is misspelled... garbage in, garbage out!

Anyone have a direction to point me in to figure out why this is happening?

Paramiko-expect Timeout Issue

Hi Team,

I'm using paramiko expect for automating one of my terminal session, however I'm facing an issue with the prompt, please find below the error

>>> import paramiko
>>> import re
>>> from paramiko_expect import SSHClientInteraction
>>> 
>>> client = paramiko.SSHClient()
>>> client.load_system_host_keys()
>>> client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> client.connect(hostname='172.19.0.120', username='default', password='default', port =2222)
>>> interact = SSHClientInteraction(client, timeout=5, encoding='utf-8', display=True, buffer_size=100000)
>>> prompt = re.escape('.*$  ')
>>> interact.expect(prompt)
CFS:default@Z18044492 [~]$ 
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/paramiko/channel.py", line 683, in recv
    out = self.in_buffer.read(nbytes, self.timeout)
  File "/usr/local/lib/python3.5/dist-packages/paramiko/buffered_pipe.py", line 160, in read
    raise PipeTimeout()
paramiko.buffered_pipe.PipeTimeout

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/paramiko_expect.py", line 144, in expect
    current_buffer = self.channel.recv(self.buffer_size)
  File "/usr/local/lib/python3.5/dist-packages/paramiko/channel.py", line 685, in recv
    raise socket.timeout()
socket.timeout
>>>

Please help me on how to solve this issue?

how to catch the return string and record,not just dispaly

from future import print_function
import traceback

import paramiko
from paramiko_expect import SSHClientInteraction

def main():
# Set login credentials and the server prompt
HOSTNAME = '1.2.3.4'
USERNAME = 'root'
PASSWORD = '123456'
PROMPT = '.*'

# Use SSH client to login
try:
    # Create a new SSH client object
    client = paramiko.SSHClient()

    # Set SSH key parameters to auto accept unknown hosts
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    # Connect to the host
    client.connect(hostname=HOSTNAME, username=USERNAME, password=PASSWORD)

    # Create a client interaction class which will interact with the host
    with SSHClientInteraction(client, timeout=10, display=True) as interact:

        interact.send('ls -l /')
        interact.expect(PROMPT, timeout=5)

        cmd_output_ls = interact.current_output_clean
        print(cmd_output_ls)

        # Send the exit command and expect EOF (a closed session)
        interact.send('exit')
        interact.expect()

except Exception:
    traceback.print_exc()
finally:
    try:
        client.close()
    except Exception:
        pass

if name == 'main':
main()


I doesn't get the result in cmd_output_ls, and at the end of programm,the result will display.
which api to catch them,not just display result

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.