如何在Paramiko的connect中添加参数,实现指定SSH命令的交互式shell?
ssh -t -l user P.P.P.P D.D.D.D with Paramiko Great question! As a fellow network engineer who’s been down the Python/Paramiko road, let’s break down exactly how to replicate your SSH jump command behavior using Paramiko.
First, let’s unpack what your original SSH command does:
ssh -t -l user P.P.P.P: Connects to your proxy serverP.P.P.Pasuser, with the-tflag forcing a pseudo-terminal allocation (critical for interactive shell functionality).- The trailing
D.D.D.Dis passed as a command to the proxy server, which triggers its internal logic to forward your session to the target deviceD.D.D.D.
To mirror this in Paramiko, we need two key pieces: connect to the proxy server, then trigger the session forwarding by passing D.D.D.D as a command (while ensuring we get that pseudo-terminal for interactivity).
Option 1: For Single Commands (Simpler)
If you just need to run a single command on D.D.D.D and capture output, use exec_command with the get_pty=True parameter (this replaces the -t flag):
import paramiko def run_command_via_proxy(proxy_host, username, target_host, password=None, key_path=None): # Initialize SSH client ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # Connect to proxy server ssh_client.connect( hostname=proxy_host, username=username, password=password, key_filename=key_path # Use this instead of password for key-based auth ) # Execute the target host command (triggers proxy forwarding) with pseudo-terminal stdin, stdout, stderr = ssh_client.exec_command(target_host, get_pty=True) # Example: Send a command to the target device's shell stdin.write("show ip interface brief\n") stdin.flush() # Read and print the output output = stdout.read().decode() print("Target Device Output:\n", output) # Check for errors error = stderr.read().decode() if error: print("Errors:\n", error) except Exception as e: print(f"Connection or command failed: {str(e)}") finally: # Clean up the connection ssh_client.close() # Replace with your actual credentials/hosts run_command_via_proxy( proxy_host="P.P.P.P", username="user", target_host="D.D.D.D", password="your_password" # Omit if using key auth )
Option 2: For Persistent Interactive Shell
If you need a full interactive session (like manually using ssh -t), use invoke_shell() to open a persistent terminal channel:
import paramiko import time def interactive_shell_via_proxy(proxy_host, username, target_host, password=None, key_path=None): ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh_client.connect( hostname=proxy_host, username=username, password=password, key_filename=key_path ) # Open an interactive shell channel shell = ssh_client.invoke_shell() shell.settimeout(10) # Send the target host command to trigger forwarding shell.send(f"{target_host}\n") time.sleep(1) # Give the proxy time to forward the session # Verify we're connected to the target device (read initial prompt) if shell.recv_ready(): initial_output = shell.recv(4096).decode() print("Connected to target device:\n", initial_output) # Example: Send an interactive command shell.send("show version\n") shell.flush() time.sleep(2) if shell.recv_ready(): command_output = shell.recv(4096).decode() print("Command Output:\n", command_output) # Keep the session open if you want to add more interaction # ... except Exception as e: print(f"Session failed: {str(e)}") finally: ssh_client.close() # Run the interactive session interactive_shell_via_proxy( proxy_host="P.P.P.P", username="user", target_host="D.D.D.D", password="your_password" )
Key Notes for Your Use Case:
- Pseudo-Terminal Requirement:
get_pty=True(forexec_command) orinvoke_shell()is non-negotiable for interactive shells, just like the-tflag in your original SSH command. Without it, most network devices won’t present a usable prompt. - Proxy Server Logic: This solution assumes your proxy server
P.P.P.Pis configured to accept the target host as a command parameter. Since your original SSH command works, this logic should hold—but if not, double-check the proxy’s configuration. - Authentication: Swap
passwordwithkey_filenameif you use SSH keys instead of password auth (far more secure for network devices!).
内容的提问来源于stack exchange,提问作者PurnaChand Medisetty




