所以我有这段代码,它没有输出任何内容,也没有运行脚本
import wexpect
import sys
child = wexpect.spawn("ssh user@ip")
child.logfile = sys.stdout
child.expect("user@ip's password:")
child.logfile = sys.stdout
child.sendline('user_password')
child.logfile = sys.stdout
child.expect('$')
child.logfile = sys.stdout
child.sendline('sudo su')
child.logfile = sys.stdout
我已经尝试了一切,红色了文档,但它仍然无法工作
以下是关于为什么你的
wexpect
脚本无法按预期工作的故障排除步骤和可能的解释:
-
sudo 提示符的变化:
-
问题:
sudo
命令通常不会显示$
作为其提示符。它更有可能显示[sudo] password for user:
或类似的内容。你的脚本正在寻找一个$
符号,该符号可能永远不会出现,导致它挂起。 -
解决方案: 将
child.expect('$')
替换为:python child.expect(r"\[sudo\] password for user: ")
这会查找更具体的 sudo 密码提示。 -
启用 sudo 密码提示:
-
问题: 你的 sudo 配置可能被设置为使用交互式基于 TTY 的提示,而
wexpect
默认情况下无法与之交互。 -
解决方案: 在远程服务器上编辑
/etc/sudoers
文件(使用visudo
命令更安全),并确保目标用户的 sudoers 条目包含requiretty
选项之前的注释字符 (#
)。这将允许sudo
在非交互式会话中工作。#Defaults requiretty
-
密码提示的处理:
-
问题:
child.sendline('sudo su')
命令本身可能会提示输入密码,而你的脚本当前没有处理这个提示。 -
解决方案: 在
sendline('sudo su')
之后添加一个child.expect()
调用来捕获密码提示,然后发送密码:python child.sendline('sudo su') child.expect(r"\[sudo\] password for user: ") child.sendline('user_password')
-
时间问题:
-
问题: 网络延迟或远程服务器上的高负载可能会导致命令执行和预期输出之间的延迟。
-
解决方案: 增加
wexpect
在超时之前的等待时间。你可以使用child.expect(pattern, timeout=seconds)
为各个expect
调用或使用child.settimeout(seconds)
全局设置超时。例如:python child.settimeout(10) # 将超时设置为 10 秒
修改后的代码:
import wexpect
import sys
child = wexpect.spawn("ssh user@ip")
child.logfile = sys.stdout
child.expect("user@ip's password:")
child.sendline('user_password')
child.expect(r"[$#] ") # 匹配 $ 或 # 提示符
child.sendline('sudo su')
child.expect(r"\[sudo\] password for user: ")
child.sendline('user_password')
child.expect(r"[$#] ") # 匹配 $ 或 # 提示符
# 现在你应该具有 root 权限
child.sendline('your_script.sh')
# ... rest of your code
其他提示:
-
调试:
如果问题仍然存在,请在每个步骤添加
print(child.before)
语句,以查看wexpect
收到的确切输出。这将有助于查明脚本挂起的位置以及预期和实际输出之间的任何差异。 - 密钥身份验证: 为了提高安全性并避免在脚本中硬编码密码,请考虑为 SSH 连接设置密钥身份验证。
- 错误处理: 实现错误处理机制以优雅地处理意外情况,例如连接失败或意外提示。
请记住用你的实际用户名、IP 地址、密码和脚本名称替换占位符值。
通过解决这些潜在问题,你应该能够创建一个可靠地通过 SSH 连接到你的服务器、提升权限并执行你的脚本的
wexpect
脚本。