• Stars
    star
    203
  • Rank 192,890 (Top 4 %)
  • Language
    Python
  • License
    MIT License
  • Created over 12 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Python expect-like extension for the Paramiko SSH library which also supports tailing logs.

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.

More Repositories

1

macbuild-ansible

Ansible code to build my Mac.
Python
43
star
2

flaskage

Flaskage is a complete and carefully designed template for use with the Flask web framework.
Python
37
star
3

multissh

A multiprocessed library written in Python and utilising Paramiko.
Python
33
star
4

painter

Your own expressive painter who colors text in your terminal.
Python
28
star
5

totalmix-volume-control

Provides control over RME TotalMix master volume via OSC.
C#
25
star
6

campies

Determines your Mac model and downloads the appropriate BootCamp package for you.
Python
16
star
7

gnome-zoomer

A simple command-line utility to allow custom-increment zooming of the GNOME desktop.
C
13
star
8

pyremedy

A simple remedy for Remedy.
Python
12
star
9

homebrew-music

Homebrew Cask definitions for various music production applications.
Ruby
12
star
10

cwdapache

Apache 2.4 connector for Crowd with Debian packaging.
C
10
star
11

venver

Simple virtualenv management and auto-switching.
Shell
3
star
12

homebrew-general

Homebrew Cask definitions for various general desktop applications (incl. legacy versions where useful).
Ruby
3
star
13

cubase-project-plugins

Determines which plugins are used in your Cubase projects.
Go
3
star
14

fgimian.github.io

Fotsies Technology Blog source code powered by the Hugo blogging engine.
CSS
2
star
15

vscode-monokai-extended

A Visual Studio Code theme based on the Sublime Text Soda Monokai theme.
2
star
16

formatizer

Literal string formatting for Python versions older than 3.6.
Python
2
star
17

cubase-project-plugins.rs

Determines which plugins are used in your Cubase projects (a little faster than the Go version).
Rust
2
star
18

hollow-knight-lilypond-scores

Piano scores of Hollow Knight music written using Lilypond.
LilyPond
1
star
19

rocksdb-rpm-el7

A forked version of the Fedora RocksDB SPEC file updated to also build on EL7
1
star
20

totalmix-volume-control.rs

Provides control over RME TotalMix master volume via OSC. The upcoming version of the app developed in Rust.
Rust
1
star