假设以下 Python 代码,我尝试打开 SSH 连接并保持打开状态并发送多个命令。我知道
communicate
不起作用,因为它会关闭连接,所以我使用 write
,但是 write
似乎会剪切命令之间的空格。
class ReadOutputThread(threading.Thread):
def __init__(self, file_obj, output_queue):
super().__init__()
self.file_obj = file_obj
self.output_queue = output_queue
self.daemon = True
def run(self):
for line in iter(self.file_obj.readline, ''):
self.output_queue.put(line.strip())
self.file_obj.close()
class YourClass:
def __init__(self, username: str, ssh_key: str, hostname: str="1.1.1.1"):
self.ssh_session = subprocess.Popen(['ssh', '-T', '-i', ssh_key, '-Y', f'{username}@{hostname}'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
universal_newlines=True, shell=False)
self.output_queue = queue.Queue()
self.stdout_thread = ReadOutputThread(self.ssh_session.stdout, self.output_queue)
self.stderr_thread = ReadOutputThread(self.ssh_session.stderr, self.output_queue)
self.stdout_thread.start()
self.stderr_thread.start()
self.execute_ssh_cmd(" ") # clean
self.ssh_session.stdin.flush()
def execute_ssh_cmd(self, command):
try:
# Debug: Print the command before sending
print(f"Executing command: {command}")
# Send the command to the SSH session
self.ssh_session.stdin.write(command)
self.ssh_session.stdin.write(" \n")
self.ssh_session.stdin.flush() # Ensure data is sent immediately
# Read the output from the queue
output_lines = []
while True:
try:
line = self.output_queue.get(timeout=1)
if command.strip() in line.strip(): # Check if the command is part of the line
continue
output_lines.append(line)
except queue.Empty:
break
return output_lines
except Exception as e:
print("Error writing to SSH session:", e)
return None
主要区块:
ssh_key_path = ""
hostname = "1.1.1.1"
username = 'user'
your_instance = YourClass(username, ssh_key_path, hostname)
output1 = your_instance.execute_ssh_cmd('ls -l')
print("Final output 1:", output1)
output2 = your_instance.execute_ssh_cmd("pwd")
print("Final output 2:", output2)
输出:
Executing command: ls
Final output 1: [': No such file or directory']
Executing command: pwd
Final output 2: ['/root']
如您所见,
ls -l
命令被删除了。
我尝试使用空格、“”、'' f 字符串格式和其他字符串选项重新输入命令。
有一个名为 paramiko 的模块,而不是使用子进程。它在 python 标准库本身中可用,不需要单独安装。该模块专门用于处理 python 中的 ssh 连接。并且使用这个模块非常简单。您的多个命令需要创建为一个列表,并迭代该列表以逐个执行。
import paramiko as pm
# Create SSH instance
ssh = pm.SSHClient()
# Automatically add host keys without prompting
ssh.set_missing_host_key_policy(pm.AutoAddPolicy())
# Connect to the SSH server
ssh.connect(hostname='<hostname>', username='<username>', password='<password>')
# keep the connection ON and run multiple commands
try:
# Open a channel
ch = ssh.invoke_shell()
# create a list containg your commands
cmds = ['cmd1', 'cmd2', 'cmd3']
for x in cmds:
# Send the command
ch.send(x + '\n')
# Wait for the command to finish
while not ch.recv_ready(): pass
# Read and print the command output
output = ch.recv(1024).decode()
print(output)
# Close the channel
ch.close()
except: print("Error writing to SSH session:")
# Close the SSH connection
finally: ssh.close()