paramiko-expect
paramiko-expect is an expect-like extension for the Paramiko SSH library, enabling scripts to interact with remote hosts via a true SSH connection in an interactive, automated fashion. It's particularly useful for automating interactions with command-line applications, shell scripts, or network devices that require 'expect'-style responses to prompts. The current version is 0.3.5, and releases are infrequent, with the last update in late 2022.
Warnings
- breaking Potential compatibility issues with newer Paramiko versions: paramiko-expect (v0.3.5) was last updated in November 2022. The underlying Paramiko library has had several major releases since then (e.g., Paramiko 3.x in December 2023), including dropping support for Python 2 and older Python 3 versions (<3.6). Using paramiko-expect with the very latest Paramiko releases might lead to unforeseen compatibility issues or unexpected behavior.
- gotcha Output cleaning can break with long commands due to TTY width: If a command sent via `send()` is long enough to wrap lines within the remote terminal's `tty_width`, the echoed command line may contain inserted spaces. This can cause `current_output_clean` to fail to correctly remove the echoed command, resulting in it appearing in your captured output or breaking subsequent `expect()` calls based on output patterns.
- gotcha Misunderstanding `expect()` patterns for multi-line output/prompts: When expecting a prompt or output that spans multiple lines, users sometimes create complex regex patterns or lists expecting every line. Often, `interact.expect()` only needs to match the *final* line or a unique part of the prompt to correctly identify the state, and over-specifying can lead to timeouts or incorrect matches.
- gotcha `SSHClientInteraction` requires a `paramiko.SSHClient` object: The `SSHClientInteraction` class is designed to wrap a `paramiko.SSHClient` instance. While the library's description mentions potential future support for `paramiko.Transport` objects, currently, passing a `Transport` object directly will result in an error or incorrect behavior.
Install
-
pip install paramiko-expect
Imports
- SSHClientInteraction
from paramiko_expect import SSHClientInteraction
Quickstart
import paramiko
import os
from paramiko_expect import SSHClientInteraction
HOSTNAME = os.environ.get('SSH_HOSTNAME', 'localhost')
USERNAME = os.environ.get('SSH_USERNAME', 'testuser')
PASSWORD = os.environ.get('SSH_PASSWORD', 'testpass')
PROMPT = r'.*\$ ' # Example prompt for a Linux shell ending with $ or #
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname=HOSTNAME, username=USERNAME, password=PASSWORD, timeout=10)
print(f"SSH connection established to {HOSTNAME}")
with SSHClientInteraction(client, timeout=10, display=True) as interact:
# Wait for the initial prompt after connection
interact.expect(PROMPT)
print(f"Initial prompt: {interact.last_match}")
# Send a command and wait for the prompt again
interact.send('uname -a')
interact.expect(PROMPT)
print(f"Uname output:\n{interact.current_output_clean}")
# Send another command
interact.send('echo Hello paramiko-expect!')
interact.expect(PROMPT)
print(f"Echo output:\n{interact.current_output_clean}")
finally:
client.close()
print("SSH connection closed.")