You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python/Paramiko脚本忽略MOTD与Banner消息并保存命令输出

Hey there! Nice work getting this far with only 3 months of Python experience—you’re already building useful automation tools, which is awesome. Let’s fix up your script to filter out those annoying banners/MOTDs and save only the actual command output to your specified file. Here’s how to do it step by step:

Key Issues to Fix

Right now, your script prints everything it receives from the SSH connection, including login banners, command echoes, and MOTDs. We need to:

  • Skip the initial login output (banner/MOTD)
  • Filter out the command lines themselves (since you don’t want to see hardware cecplus... repeated in your output)
  • Write only the actual command results to your target file instead of just printing them

Modified Script with Explanations

Here’s the updated code with these changes— I’ll highlight the key tweaks below:

from __future__ import print_function
import threading
import paramiko
import getpass
import time
import os
import sys
os.system('clear')

class ssh(object):
    shell = None
    client = None
    transport = None
    output_file = None
    sent_commands = []  # Track commands we've sent to filter echoes

    def __init__(self, address, username, password, output_file):
        print('Connecting to server on ip', str(address.strip()) + '.')
        self.output_file = output_file
        self.client = paramiko.client.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
        try:
            self.client.connect(address.strip(), username=username, password=password, look_for_keys=False)
            self.transport = self.client.get_transport()  # Reuse the client's transport instead of creating a new one
            thread = threading.Thread(target=self.process)
            thread.daemon = True
            thread.start()
        except Exception as e:
            print(f'Failed to connect to {address.strip()}: {str(e)}')
            self.client = None

    def close_connection(self):
        if self.client is not None:
            self.client.close()
            if self.transport is not None:
                self.transport.close()

    def open_shell(self, prompt='#'):  # Add prompt parameter to match your server's prompt
        if self.client is None:
            print("No active connection to open shell on.")
            return
        self.shell = self.client.invoke_shell()
        # Read and discard initial banner/MOTD until we see the prompt
        while True:
            if self.shell.recv_ready():
                data = self.shell.recv(1024).decode('utf-8')
                if prompt in data:
                    break  # Stop once we get to the command prompt

    def send_shell(self, command):
        if self.shell and self.client is not None:
            self.sent_commands.append(command)
            self.shell.send(command + '\n')
        else:
            print("Shell not opened or connection failed.")

    def process(self):
        if self.client is None:
            return
        while True:
            if self.shell is not None and self.shell.recv_ready():
                alldata = self.shell.recv(1024).decode('utf-8')
                while self.shell.recv_ready():
                    alldata += self.shell.recv(1024).decode('utf-8')
                
                # Split into lines and filter unwanted content
                lines = alldata.split(os.linesep)
                for line in lines:
                    stripped_line = line.strip()
                    # Skip empty lines, command echoes, and any leftover prompt text
                    if not stripped_line:
                        continue
                    if any(cmd in stripped_line for cmd in self.sent_commands):
                        continue
                    if stripped_line.endswith('#') or stripped_line.endswith('>'):
                        continue
                    
                    # Write the clean output to file and print (optional)
                    print(stripped_line)
                    self.output_file.write(stripped_line + os.linesep)
                    self.output_file.flush()  # Ensure data is written immediately

header = "################## WHAT DO YOU WANT TO DO?? ##################"
headlen = len(header) - 2
secondline = "|" + (" " * headlen) + "|"
thirdline = "|" + " 1. Run the daily ATM Script." + (" " * 30) + "|"
fourthline = "|" + " 2. Run a single command on the entire ATM network" + (" " * 9) + "|"
print(header)
print(secondline)
print(secondline)
print(thirdline)
print(fourthline)
print(secondline)
print(secondline)
print("#" * len(header))
choice = raw_input("Choose your destiny: ")

while choice:
    if choice == "1":
        print(' \n##### STARTING PROGRAM #####\n')
        sshUsername = getpass.getpass(prompt='ENTER USERNAME: ')
        sshPassword = getpass.getpass('ENTER PASSWORD: ')
        filename = raw_input("What filename dost thou chooseth? ")
        # Open file in write mode (use 'a' if you want to append instead)
        with open(filename, 'w') as writefile:
            def main():
                with open("host.csv", "r") as r:
                    for address in r:
                        address = address.strip()
                        if not address:
                            continue  # Skip empty lines in host.csv
                        print(f"\nProcessing {address}...")
                        connection = ssh(address, sshUsername, sshPassword, writefile)
                        if connection.client is None:
                            writefile.write(f"FAILED TO CONNECT TO: {address}{os.linesep}")
                            continue
                        try:
                            connection.open_shell()  # Adjust prompt here if your server uses something else like '>'
                            time.sleep(1)
                            commands = [
                                'hardware cecplus timing references show',
                                'power',
                                'hard port show',
                                'sig show',
                                'conn spvcc pp show',
                                'interface sonet path near total'
                            ]
                            for cmd in commands:
                                connection.send_shell(cmd)
                                time.sleep(1)  # Adjust sleep time based on how long commands take to run
                            time.sleep(2)  # Give time for final output to come through
                        except Exception as e:
                            error_msg = f'Failed to run commands on {address}: {str(e)}'
                            print(error_msg)
                            writefile.write(error_msg + os.linesep)
                        finally:
                            connection.close_connection()
            main()
        print(f"\nAll tasks completed! Output saved to {filename}")
        break

    elif choice == "2":
        COMMAND = raw_input("INPUT A SINGLE COMMAND TO RUN ON THE ENTIRE ATM NETWORK: ")
        print(' \n##### STARTING PROGRAM #####\n')
        sshUsername = getpass.getpass(prompt='ENTER USERNAME: ')
        sshPassword = getpass.getpass('ENTER PASSWORD: ')
        filename = raw_input("What filename dost thou chooseth? ")
        with open(filename, 'w') as writefile:
            def main():
                with open("host.csv", "r") as r:
                    for address in r:
                        address = address.strip()
                        if not address:
                            continue
                        print(f"\nProcessing {address}...")
                        connection = ssh(address, sshUsername, sshPassword, writefile)
                        if connection.client is None:
                            writefile.write(f"FAILED TO CONNECT TO: {address}{os.linesep}")
                            continue
                        try:
                            connection.open_shell()
                            time.sleep(1)
                            connection.send_shell(COMMAND)
                            time.sleep(2)
                        except Exception as e:
                            error_msg = f'Failed to run command on {address}: {str(e)}'
                            print(error_msg)
                            writefile.write(error_msg + os.linesep)
                        finally:
                            connection.close_connection()
            main()
        print(f"\nAll tasks completed! Output saved to {filename}")
        break

    else:
        print("If thou dost not Enter 1 or 2 thou willest not proceed")
        choice = raw_input("Choose your destiny: ")

Key Tweaks Explained

  1. SSH Class Improvements:

    • Added an output_file parameter to the __init__ method so each connection knows where to write results.
    • Added a sent_commands list to track commands we’ve sent—this lets us filter out the command echoes from the output.
    • Updated open_shell to read and discard the initial banner/MOTD until it detects the server’s command prompt (adjust the prompt parameter if your server uses something like > instead of #).
    • The process method now filters out empty lines, command echoes, and prompt text, then writes clean output to your file.
  2. Main Program Fixes:

    • Now uses with open(...) for both the output file and host.csv to ensure files are properly closed.
    • Skips empty lines in host.csv to avoid errors.
    • Adds error messages to the output file so you can track failed connections/commands.
    • Adjusted sleep times to give commands enough time to run and return output (you might need to tweak these based on your servers’ response speed).
  3. Other Small Fixes:

    • Reused the client’s transport instead of creating a new one (avoids redundant connections).
    • Added .strip() to IP addresses to remove newline characters from host.csv.
    • Flushes the output file after each write to ensure data is saved immediately.

Give this a try—you should now get only the actual command results in your output file, with no banners or MOTDs cluttering things up. Let me know if you need to adjust the prompt or sleep times for your specific servers!

内容的提问来源于stack exchange,提问作者wiz0rd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:12:27