本文目录导读:

- 使用 pexpect (Python)
- 使用 subprocess (Python)
- 使用 expect (Shell)
- 使用 Python 的 basic 方法
- 使用 tmux/screen 模拟
- 高级 pexpect 示例
- Python + pty 完整示例
- 最佳实践建议:
使用 pexpect (Python)
最常用的方法,可以模拟终端交互:
import pexpect
# 启动一个程序
child = pexpect.spawn('bash')
# 等待提示符出现
child.expect(r'\$')
# 发送命令
child.sendline('echo "Hello World"')
child.expect(r'Hello World')
child.sendline('exit')
# 交互式控制
child = pexpect.spawn('ssh user@host')
child.expect('password:')
child.sendline('mypassword')
child.expect(r'\$')
child.sendline('ls -la')
使用 subprocess (Python)
import subprocess
import time
# 方式1:直接执行
result = subprocess.run(['echo', 'hello'], capture_output=True, text=True)
print(result.stdout)
# 方式2:管道交互
process = subprocess.Popen(
['python3', '-i'], # 启动交互式Python
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
process.stdin.write("print('hello')\n")
process.stdin.flush()
time.sleep(1)
# 读取输出
output = process.stdout.readline()
print(output)
使用 expect (Shell)
#!/usr/bin/expect -f # 启动交互程序 set timeout 10 spawn ssh user@host # 等待密码提示 expect "password:" send "mypassword\r" # 等待命令提示符 expect "$" send "ls -la\r" # 发送多个命令 expect "$" send "cd /tmp\r" expect "$" send "echo 'test' > file.txt\r" # 退出 expect "$" send "exit\r" expect eof
使用 Python 的 basic 方法
import os
import pty
import select
import subprocess
def interactive_terminal():
# 创建伪终端
master, slave = pty.openpty()
# 启动bash
process = subprocess.Popen(
['bash'],
stdin=slave,
stdout=slave,
stderr=slave,
close_fds=True
)
# 发送命令
os.write(master, b'echo "Hello"\n')
# 读取输出
while True:
r, _, _ = select.select([master], [], [], 0.1)
if r:
output = os.read(master, 1024)
print(output.decode(), end='')
if process.poll() is not None:
break
使用 tmux/screen 模拟
#!/bin/bash # 使用 tmux 模拟终端输入 # 创建新会话 tmux new-session -d -s mysession # 发送命令 tmux send-keys -t mysession "echo 'Hello'" Enter # 发送多行命令 tmux send-keys -t mysession "for i in 1 2 3; do echo \$i; done" Enter # 读取输出 tmux capture-pane -t mysession -p # 退出会话 tmux kill-session -t mysession
高级 pexpect 示例
import pexpect
import re
class TerminalEmulator:
def __init__(self, command):
self.child = pexpect.spawn(command, encoding='utf-8')
self.child.logfile = open('terminal.log', 'w')
def execute(self, command, expected_pattern=None, timeout=10):
"""执行命令并等待结果"""
self.child.sendline(command)
if expected_pattern:
try:
self.child.expect(expected_pattern, timeout=timeout)
return self.child.before + self.child.after
except pexpect.TIMEOUT:
return f"命令超时: {command}"
else:
self.child.expect(pexpect.EOF, timeout=timeout)
return self.child.before
def interact(self):
"""进入交互模式"""
print("进入交互模式,按 Ctrl+] 退出")
self.child.interact()
# 使用示例
if __name__ == "__main__":
term = TerminalEmulator('bash')
# 执行命令
result = term.execute('ls -la', expected_pattern=r'total|找不到|error')
print("命令执行结果:", result)
# 执行复杂命令
result = term.execute(
'python3 -c "import sys; print(sys.version)"',
expected_pattern=r'Python'
)
print("Python版本:", result)
Python + pty 完整示例
import os
import pty
import subprocess
import time
class PTYTerminal:
def __init__(self, command):
self.master, self.slave = pty.openpty()
self.process = subprocess.Popen(
command,
stdin=self.slave,
stdout=self.slave,
stderr=self.slave,
close_fds=True
)
os.close(self.slave)
def send_command(self, command):
os.write(self.master, command.encode() + b'\n')
def read_output(self, timeout=1):
output = b''
end_time = time.time() + timeout
while time.time() < end_time:
import select
r, _, _ = select.select([self.master], [], [], 0.1)
if r:
try:
data = os.read(self.master, 1024)
if not data:
break
output += data
except OSError:
break
return output.decode()
def close(self):
self.process.terminate()
os.close(self.master)
# 使用示例
term = PTYTerminal(['bash'])
term.send_command('echo "Test"')
time.sleep(0.5)
output = term.read_output()
print("收到的输出:", output)
term.close()
最佳实践建议:
- 对于简单任务:使用
subprocess - 需要交互:使用
pexpect - 需要完全模拟终端:使用
pty或tmux - 测试场景:使用
pexpect或expect写测试脚本
这些方法能有效模拟终端输入,适用于自动化测试、教学演示、批量操作等场景。