基于Paramiko实现多IP批量执行SSH命令的技术求助
Hey there! No worries about being a Python newbie—we all start somewhere, and your foundation with Paramiko is already solid. Let's tweak your code to handle batch execution across multiple IPs from your text file.
First, let's fix a few small syntax issues in your original SSH function, then integrate the IP list reading logic to enable batch operations.
1. Fix Syntax & Hardcoding Issues
Your original ssh_comm function has two minor problems:
- The line handling command execution and output reading has incorrect syntax
- You're hardcoding username/password instead of using the function parameters
Here's the corrected ssh_comm function:
def ssh_comm(ip, user, password, cmd): try: print(f"Connecting to {ip}...") client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Use the passed credentials instead of hardcoding client.connect(ip, port=port, username=user, password=password, timeout=10) ssh_session = client.get_transport().open_session() if ssh_session.active: # Split command execution and output reading into separate lines ssh_session.exec_command(cmd) buffer = ssh_session.recv(4096).decode("utf-8") print(f"Output from {ip}:\n{buffer}") client.close() except paramiko.AuthenticationException: print(f"Authentication failed for {ip}") # Call your ssh_comm2 here with alternative credentials if needed # ssh_comm2(ip, alt_user, alt_password, cmd) except Exception as e: print(f"Error connecting to {ip}: {str(e)}")
2. Integrate Batch IP Execution
Now let's combine your IP list reading code with the SSH function to run commands across all machines in your text file. We'll make it interactive so you can input credentials and a single command to run on every IP.
Full Modified Code
import paramiko import sys import os import time port = 22 def ssh_comm(ip, user, password, cmd): try: print(f"Connecting to {ip}...") client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(ip, port=port, username=user, password=password, timeout=10) ssh_session = client.get_transport().open_session() if ssh_session.active: ssh_session.exec_command(cmd) buffer = ssh_session.recv(4096).decode("utf-8") print(f"Output from {ip}:\n{buffer}") client.close() except paramiko.AuthenticationException: print(f"Authentication failed for {ip}") # Uncomment and adjust if you have alternative credentials to try # ssh_comm2(ip, alternative_user, alternative_password, cmd) except Exception as e: print(f"Error connecting to {ip}: {str(e)}") def batch_ssh_execution(): # Read IP list from file (fix the path to your actual file location) iplist_path = 'IP TEXT FILE LOCATION.txt' ip_list = [] with open(iplist_path, 'r') as fp: for line in fp: ip = line.strip() if ip: # Skip empty lines in the file ip_list.append(ip) if not ip_list: print("No valid IP addresses found in the file.") return # Get user input for credentials and command user = input("Enter SSH username: ") password = input("Enter SSH password: ") cmd = input("Enter command to execute (e.g., reboot): ") # Loop through every IP and run the command for ip in ip_list: ssh_comm(ip, user, password, cmd) # Add a delay if running reboot to give machines time to restart if cmd.lower() == 'reboot': print(f"Waiting 60 seconds for {ip} to reboot...") time.sleep(60) if __name__ == "__main__": batch_ssh_execution()
3. Key Improvements Explained
- Batch IP Handling: Reads all IPs into a list first, then iterates through them to run the command consistently
- Enhanced Error Handling: Catches more exceptions (like connection timeouts) to help diagnose issues
- Flexible Credentials: Takes username/password as input instead of hardcoding, making it reusable for different environments
- Clear Output: Adds status messages so you can track which IP is being processed and what the result is
- Reboot Delay: Includes a 60-second wait if you run a reboot command (adjust the sleep time as needed for your machines)
Optional Extension
If you need to use different credentials for different IPs, you can modify the IP file to use a CSV format (e.g., ip_address,username,password) and parse each line into a dictionary to pass the correct credentials to ssh_comm.
内容的提问来源于stack exchange,提问作者sonashii

