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

向Expect脚本传递密码参数失败,请求问题排查指导

问题描述

我写了一个需要传递密码作为参数的expect脚本:

#!/usr/bin/expect -f
set password [lindex $argv 0];
spawn iroot
expect ".* password for"
sleep 3
send "$password\r"
sleep 5
send "dmidecode -t system | grep Manufacturer > /tmp/manufacdetails.txt\r"
send "exit\r"
interact

尝试用命令./getmanufacdetailsTest.sh password123执行,但脚本无法正常工作,请问哪里操作出错了?


可能的问题及解决方法

这里有几个常见的坑可能导致你的脚本失效,咱们一个个排查:

1. 脚本缺少执行权限

首先检查脚本是否有可执行权限,如果没有的话系统会直接拒绝执行。执行以下命令添加权限:

chmod +x getmanufacdetailsTest.sh

2. 匹配模式不够精准(最可能的原因)

你的expect ".* password for"匹配规则太宽泛,而且大概率和iroot实际输出的密码提示不匹配。比如很多工具的密码提示是类似Password for user:或者直接Password:,这种情况下你的正则匹配根本抓不到目标内容。

建议改成更精准的匹配,或者用正则表达式捕获核心提示,比如:

# 匹配包含"password for"的任意行,兼容末尾带冒号的情况
expect -re "password for.*:"

如果能确定实际的提示文本(比如你手动执行iroot看到的是Enter your password:),直接写死匹配字符串会更可靠:expect "Enter your password:"。

3. 固定sleep不可靠,应该用expect等待而非延迟

用sleep 3和sleep 5是很不稳定的——不同环境下命令执行速度差异很大,可能sleep时间不够导致发送密码时提示还没出现,或者sleep太久完全是浪费时间。

正确的做法是用expect等待下一个预期的系统反馈,比如输入密码后等待root shell的提示符(比如#),再发送后续命令:

send "$password\r"
# 等待root shell的提示符,根据你的实际环境调整符号
expect "#"
send "dmidecode -t system | grep Manufacturer > /tmp/manufacdetails.txt\r"
# 等待命令执行完成后的提示符再退出
expect "#"
send "exit\r"

4. 最后用expect eof替代interact更合适

interact是用来让用户和spawn的进程手动交互的,但你已经发送了exit命令,进程应该正常退出,用expect eof等待进程结束更合理,避免脚本莫名卡住:

send "exit\r"
expect eof

5. 增加参数校验(可选优化)

可以在脚本开头加个判断,如果用户没传递密码参数就直接提示用法,避免无意义的执行:

if { $argc != 1 } {
    puts "Usage: $argv0 <password>"
    exit 1
}
set password [lindex $argv 0]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:06:53